Search code examples
c#.netinversion-of-controlunity-container

Dependency Injection with priority / fallback and generics in Unity


Let's say I have a generic interface and a generic class that implements it.

interface IRepository<TModel> { }

[RegisterGeneric(typeof(IRepository<>))]
class GenericRepository<TModel> : IRepository<TModel> { }

And two models User and Order. User has nothing special so it uses the generic repository implementation. Order is different, so I have a specific repository.

[Register(typeof(IRepository<Order>))]
class OrderRepository : GenericRepository<Order> { }

Meanwhile you can see I use two attributes so that I can scan the attributes and automatically register them to Unity when the application starts. What I want is:

  1. IRepository<User> is mapped to GenericRepository<User>
  2. IRepository<Order> is mapped to OrderRepository

for those new models in the feature, if a specific repository is added(like Order), the interface should be mapped to the specific implementation. Otherwise it's mapped to the generic one. How can I implement the priority function?


Solution

  • In Unity, when you make multiple registrations, Unity will build up a collection of registrations for you where the last registration becomes the 'default' registration. So in that respect, you should be able to do the following:

    container.RegisterType(typeof(IRepository<>), typeof(GenericRepository<>));
    
    // Override multiple specific implementations (I image batch registration here)
    container.RegisterType(typeof(IRepository<Order>), typeof(OrderRepository));
    container.RegisterType(typeof(IRepository<Customer>), typeof(CustomerRepository));