Hi I have been having trouble trying to tell Unity that for an Interface if it has multiple implementations , I want it to inject them in different classes.Here is what I mean:
Let's say I have an interface IProductCatalogService
and two implementations
ProductCatalog : IProductCatalogService
and ProductCatalogService : IProductCatalogService
.
How would I go about telling Unity that for Class A I want in my constructor passed an instance of type ProductCatalog
and for Class B
I want an instance of ProductCatalogService
.
I am using Unity in an ASP.NET Web API project and I have set the resolver in the GLobalConfiguration
.
For simple 1 to 1 registrations everything works.
Here is what I have tried but it does not seem to work:
public class DependencyServiceModel
{
public Type From { get; set; }
public Type To { get; set; }
public IEnumerable<Type> ForClasses { get; set; }
}
public void RegisterTypeForSpecificClasses(DependencyServiceModel dependencyService)
{
foreach (var forClass in dependencyService.ForClasses)
{
string uniquename = Guid.NewGuid().ToString();
Container.RegisterType(dependencyService.From,
dependencyService.To, uniquename);
Container.RegisterType(forClass, uniquename,
new InjectionConstructor(
new ResolvedParameter(dependencyService.To)));
}
}
In the DependencyServiceModel
, From
is the interface, To
is the object to witch I want to instantiate and ForClasses
are the Type for which I want to use the To
Object.
A class that lets you specify a factory method the container will use to create the object.
A class that holds the collection of information for a constructor, so that the container can be configured to call this constructor.
Before Unity resolves the dependencies, we need to register the type-mapping with the container, so that it can create the correct object for the given type. Use the RegisterType() method to register a type mapping. Basically, it configures which class to instantiate for which interface or base class.
The Unity Container (Unity) is a full featured, extensible dependency injection container. It facilitates building loosely coupled applications and provides developers with the following advantages: Simplified object creation, especially for hierarchical object structures and dependencies.
Nice to know. If you register multiple types to an Interface like belove;
container.RegisterType<ITransactionsService, EarningsManager>();
container.RegisterType<ITransactionsService, SpendingsManager>();
you can not get the list of types by;
IEnumerable<ITransactionsService> _transactionsService;
here in the list will be always the last registered type ( SpendingsManager.)
To prevent this situation ;
container.RegisterType<ITransactionsService, EarningsManager>("EarningsManager");
container.RegisterType<ITransactionsService, SpendingsManager>("SpendingsManager");
You have to change the code in this way.
In the example below you have an interface implemented twice and injected on demand into two different client classes, just as you request. The trick is to use named registrations.
class Program
{
static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IFoo, Foo1>("Foo1");
container.RegisterType<IFoo, Foo2>("Foo2");
container.RegisterType<Client1>(new InjectionConstructor(new ResolvedParameter<IFoo>("Foo1")));
container.RegisterType<Client2>(new InjectionConstructor(new ResolvedParameter<IFoo>("Foo2")));
Client1 client1 = container.Resolve<Client1>();
Client2 client2 = container.Resolve<Client2>();
}
}
public interface IFoo
{
}
public class Foo1 :IFoo
{
}
public class Foo2 : IFoo
{
}
public class Client1
{
public Client1(IFoo foo)
{
}
}
public class Client2
{
public Client2(IFoo foo)
{
}
}
This is most probably what you do wrong:
Container.RegisterType(forClass, uniquename,
new InjectionConstructor(
new ResolvedParameter(dependencyService.To)));
You create a named registration for your concrete class. Instead you should have
Container.RegisterType(forClass, null,
new InjectionConstructor(
new ResolvedParameter(dependencyService.To, uniquename)));
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