For the following interfaces and classes, how do I use Unity Container to Fluently (programatically) wire it up so that FooController
gets an instance of ARepository
and BarController
gets an instance of BRepository
via constructor injection?
public interface IRepository
{
}
public class ARepository : IRepository
{
}
public class BRepository : ARepository
{
}
public class FooController
{
public FooController(IService service, IRepository repository)
{
}
}
public class BarController
{
public BarController(IService service, IRepository repository)
{
}
}
Using the delegate func Introduce three implementation classes as below- three different classes where we have implemented the same interface. ASP.NET Core has built-in support for dependency injection. However, multiple implementations of an interface in ASP.NET Core is tricky.
A class that holds the collection of information for a constructor, so that the container can be configured to call this constructor.
A class that lets you specify a factory method the container will use to create the object.
Dependency injection is a pattern to allow your application to inject objects on the fly to classes that need them, without forcing those classes to be responsible for those objects. It allows your code to be more loosely coupled, and Entity Framework Core plugs in to this same system of services.
You can achieve this at registration time by telling each controller registration how to resolve its constructor parameters.
container.RegisterType<FooController>(new InjectionConstructor(
new ResolvedParameter<IService>(), new ResolvedParameter<ARepository>());
container.RegisterType<BarController>(new InjectionConstructor(
new ResolvedParameter<IService>(), new ResolvedParameter<BRepository>());
I would highly recommend against creating a dedicated/local/injected UnityContainer for each type like one of the posters suggested.
This can be approached in two ways.
One is by specifically defining the resolving in registration time as TylerOhlsen suggested. This is a good solution, though if you register later both ARepository and BRepository as implementations for IRepository, you still need to deal with the fact you have two implenetations for the same interface, and if a third class will someday require an implementation of IRepository, without defining it specifically in the registration, it will get an unpredictable instance.
The second option, which is slightly safer, is registering a factory for IRepository. The simplest example would be using a string as the key, like this:
// Create a resolver(abstract factory) for the IRepository interface type
var resolver = myContainer.Resolve<Func<IRepository>>();
// ... other code here...
// Register mappings for the IRepository interface to appropriate concrete types
myContainer.RegisterType<IRepository, ARepository>("A");
myContainer.RegisterType<IRepository, BRepository>("B");
Then in the implementation of FooController and BarController receive the func factory by injection and select the right instance.
public class FooController
{
IRepository repository;
public FooController(IService service, Func<IRepository> repositoryFactory)
{
repository = repositoryFactory("A");
}
}
You can read more about this here: http://msdn.microsoft.com/en-us/library/ff660854%28v=pandp.20%29.aspx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With