C # Generics: the best way to map a generic type to another?

UPDATE: Didn't give a great example. Hope this is better now.

Is there a better way:

(typeof(TRepository) == typeof(UserClass))

Used here in writing:

public static IBaseRepository<TClass> GetRepository<TClass>() where TClass : IDataEntity
{
  IBaseRepository<TClass> repository = null;

  if (typeof(TClass) == typeof(UserClass))
  {
     repository = (IBaseRepository<TClass>)new UserClassRepository();
  }

  if (typeof(TClass) == typeof(PostClass))
  {
     repository = (IBaseRepository<TClass>)new PostClassRepository();
  }

  return repository;
}

If something like this does a lot, I hope it’s better there than running a type from several times.

+3
source share
3 answers

What you are doing here is the poor man inverting the control container . Tie up, learn the concepts of dependency injection and control inversion , and then you can write code like this:

IIoCContainer container = new IoCContainer();
container.RegisterType<IBaseRepository<UserClass>, UserClassRepository>();
container.RegisterType<IBaseRepository<PostClass>, PostClassRepository>();
var userClassRepository = container.Resolve<IBaseRepository<UserClass>>();

( ) . (, , ). , , ( new ConcreteType()) .

(, Class ( User Post, UserClass PostClass).)

+6

:

if (typeof(TRepository).IsAssignableFrom(typeof(UserClass)))

, UserClassRepository IBaseRepository, .

- ? , , , .

+2

You really haven't defined what you mean by "better." However, one way I can do this is to create a custom attribute for each TClass that defines the repository, and read that attribute in your method GetRepository. It uses some reflection, but it is more elegant than a large if-else, and lighter than a full injection environment. Quick example:

Attribute

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
public class RepositoryAttribute : Attribute
{
    public RepositoryAttribute(Type repositoryType)
    {
        this.RepositoryType = repositoryType;
    }

    public Type RepositoryType { get; private set; }
}

Entity Class:

[Repository(typeof(UserClassRepository))]
public class UserClass
{
    // Class code
    // ...
}

Factory Method:

public static IBaseRepository<TClass> GetRepository<TClass>()
  where TClass : IDataEntity
{
    Type t = typeof(TClass);
    RepositoryAttribute attr =
        (RepositoryAttribute)Attribute.GetCustomAttribute(t,
          typeof(RepositoryAttribute), false);
    if (attr != null)
    {
        return (IBaseRepository<TClass>)Activator.CreateInstance(attr.RepositoryType);
    }
    return null;
}
+1
source

Source: https://habr.com/ru/post/1725679/


All Articles