I keep running into this scenario: suppose I have interface IFoo
and several implementations, like RedFoo : IFoo
and BlackFoo : IFoo
. I then have classes that take IFoo
in the constructor:
class BlackFooUser
{
public BlackFooUser(IFoo foo, other_parameters_here) {...}
}
class RedFooUser
{
public RedFooUser(IFoo foo, other_parameters_here) {...}
}
How do I tell the container to resolve all other parameters as usual, but always use BlackFoo
when constructing BlackFooUser
, and always use RedFoo
when constructing RedFooUser
? I know I can use ParameterOverride
when calling Resolve()
, but I want it to be the same whenever a Red/BlackFooUser
is resolved, so this should go into RegisterType
or RegisterFactory
.
I can do something like
container.RegisterFactory<RedFooUser>(c=>new RedFooUser(c.Resolve<RedFoo>(), other_parameters_here));
but this is quite verbose, and this will have to change every time I add new parameters.
Is there a better way?
UPDATE I am specifically looking to do this through container registrations, without modifying the classes involved. There are multiple reasons for that, but it boils down to this:
I submitted an issue to UnityContainer repo, and the response by Eugene Sadovoy pushed me towards this answer.
To avoid an infinite loop, one can register the default factory as named registration, and invoke it from the default, unnamed factory, along the lines of (sorry, I changed the names a little compared to the question):
container
.RegisterType<SpecialFooUser>("stdreg")
.RegisterFactory<SpecialFooUser>(
c => c.Resolve<SpecialFooUser>("stdreg",
new DependencyOverride<IFoo>(c.Resolve<SpecialFoo>()))
);
This works, but looks quite verbose, so I wrote a few extension methods and classes (~100 lines of code total) to make it less verbose and more expressive:
container.Register(
new CustomFactory<SpecialFooUser>()
.DependencyOverride<IFoo, SpecialFoo>());
The complete source code is on GitHub: https://github.com/ikriv-samples/UnityResolveOverrideFactory