简体   繁体   中英

Unity Dependency Injection - Method with Generic Repository return type

I am having trouble figuring out how to get Unity to work with my generic repository. Here is my basic setup:

public static Repository<IEntity> GetRepository()
{
     //This is of type CustomerRepository
     return unitOfWork.CustomerRepository;         
}


CustomerRepository  : Repository<Customer>, ICustomerRepository
Repository<TEntity> : IRepository<TEntity> where TEntity : class, IEntity

ICustomerRepository : IRepository<Customer>
IRepository<TEntity> : IDisposable where TEntity : class, IEntity

Customer : IEntity

The error on return unitOfWork.CustomerRepository is:

Cannot implicitly convert type 'CustomerRepository' to 'Repository'

I'm totally lost, I have tried so many ways of registering it that I am starting to think I need to do something else to achieve what I want... No idea what I am doing with the RegisterTypes at this point, as you can see:

container.RegisterType<IEntity, Customer>();
container.RegisterType(typeof(Repository<Customer>), typeof(CustomerRepository));
container.RegisterType(typeof(CustomerRepository), typeof(Repository<Customer>));

container.RegisterType(typeof(Repository<IEntity>), typeof(Repository<Customer>));
container.RegisterType(typeof(Repository<Customer>), typeof(Repository<IEntity>));


container.RegisterType(typeof(Repository<>), typeof(Repository<IEntity>));
container.RegisterType(typeof(Repository<IEntity>), typeof(Repository<>));

            //---------

container.RegisterType(typeof(IRepository<Customer>), typeof(Repository<IEntity>));
container.RegisterType<IRepository<Customer>, CustomerRepository>();
container.RegisterType(typeof(Repository<IEntity>), typeof(CustomerRepository));


            //--------------------
container.RegisterType(typeof(IRepository<>), typeof(Repository<>));
container.RegisterType<ICustomerRepository, CustomerRepository>();

container.RegisterType<IRepository<Customer>, ICustomerRepository>();
container.RegisterType<Repository<Customer>, CustomerRepository>();
container.RegisterType<IRepository<Customer>, CustomerRepository>();

container.RegisterType<IRepository<Customer>, ICustomerRepository>();
container.RegisterType<Repository<Customer>, CustomerRepository>();
container.RegisterType<IRepository<Customer>, CustomerRepository>();

container.RegisterType(typeof(IRepository<IEntity>), typeof(IRepository<Customer>));

None of these ways of registering it are helping.

EDIT 1:

How can I get this to work?:

public static Repository<TEntity> GetRepository<TEntity>(string entityName, string conectionName) where TEntity : class, IEntity
{
     var unitOfWork = new UnitOfWork(connectionName);

     switch(entityName){
     case "Customer":
           return unitOfWork.CustomerRepository;
     }

     return null;
}

If I understand correctly, and break down your code in more lines, you are doing this:

public static Repository<IEntity> GetRepository()
{
    CustomerRepository repository1 = unitOfWork.CustomerRepository;
    Repository<IEntity> repository2 = repository1;
    return repository2;
}

So indirectly you are assiging a value of type CustomerRepository to type Repository<IEntity> , which will not work, since Repository<IEntity> is not a base type of CustomerRepository . On the other hand, type Repository<Customer> is the base class of CustomerRepository , so assigning CustomerRepository to Repository<Customer> will work.

* EDIT *

Based on your comments, some new insights:

public static Repository<TEntity> GetRepository<TEntity>()
    where TEntity : class, IEntity
{
    if (typeof(TEntity) == typeof(Customer))
        return (Repository<TEntity>)(object)new Repository<Customer>();
    if (typeof(TEntity) == typeof(Product))
        return (Repository<TEntity>)(object)new Repository<Product>();
    throw new Exception("Entity of type " + typeof(IEntity).Name + " is not supported.");
}

Or... using reflection (slower):

public static Repository<TEntity> GetRepository<TEntity>()
    where TEntity : class, IEntity
{
    Type repositoryType = typeof(Repository<>).MakeGenericType(typeof(TEntity));
    return (Repository<TEntity>)Activator.CreateInstance(repositoryType);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM