zaq
zaq

Reputation: 2661

Injecting specific implementations using Unity

I have 2 implementations of an interface where I need to inject the first implementation into one service and the second implementation into another. Each service is also injected with other dependencies that do not have multiple implementations.

So far, I have something like this:

public FirstService(IDataRepository dr, IOtherRepository or)
{
    this.DataRepository = dr;
    this.OtherRepository = or;
}

public SecondService(IDataRepository dr, IAnotherRepository ar)
{
    this.DataRepository = dr;
    this.OtherRepository = ar;
}

Then in my bootstrapper I have:

container.RegisterType<IDataRepository, FirstDataRepository>("First");
container.RegisterType<IDataRepository, SecondDataRepository>("Second");
container.RegisterType<IOtherRepository ,OtherRepositor>();
container.RegisterType<IAnotherRepository ,AnotherRepository>();

container.RegisterType<IFirstService, FirstService>(new InjectionConstructor(new ResolvedParameter<IDataRepository>("First")));
container.RegisterType<ISecondService, SecondService>(new InjectionConstructor(new ResolvedParameter<IDataRepository>("Second")));

When I run my application I get the error: "FirstService does not have a constructor that takes the parameters (IDataRepository)."

Do I need to also specify the instance of IOtherRepository that needs to be injected now that I am specifically specifying the instance of IDataRepository that should be injected? Or am I doing something else wrong?

My actual constructor takes 6 arguments and it would be a pain to have to manually inject each of them just because one of them has multiple implementations.

Upvotes: 3

Views: 1722

Answers (2)

Nachiket Mehta
Nachiket Mehta

Reputation: 310

container.RegisterType<IFirstService, FirstService>(new InjectionConstructor(new ResolvedParameter<IDataRepository>("First"), new ResolvedParameter<IOtherRepository>()));
container.RegisterType<ISecondService, SecondService>(new InjectionConstructor(new ResolvedParameter<IDataRepository>("Second"), new ResolvedParameter<IAnotherRepository>()));

You need to resolve the second constructor parameter.

Upvotes: 0

Sebastian Weber
Sebastian Weber

Reputation: 6806

You don't have to specify the values for the other parameters but you must specify their Type so that Unity can identify which constructor to use.

The registration for IFirstService would then look like this

container.RegisterType<IFirstService, FirstService>(new InjectionConstructor(new ResolvedParameter<IDataRepository>("First"), typeof(IOtherRepository)));

The TecX project on codeplex includes the ClozeInjectionConstructor that deals with situations like these where you only want to specify a single parameter. See the sourcecode in the TecX.Unity project.

Btw: 6 parameters for a constructor are a code smell for the constructor over injection anti-pattern.

Upvotes: 3

Related Questions