Delegate factory with Dependency.OnComponent and TypedFactoryFacility
See original GitHub issueHello, i have been doing some refactoring of our container mess and it seems i found something weird. When using delegate factory and Dependecny.OnComponent at once the factory gets wrong component resolved, i boiled it down to this code:
public interface IInterface {}
public class C1 : IInterface {}
public class C2 : IInterface {}
public class Root
{
private IInterface _I;
public Root(Func<IInterface> factory)
{
//here i expect to get instance of C2 but get C1
_I = factory();
}
}
public void Main()
{
_container = new WindsorContainer();
_container.AddFacility<TypedFactoryFacility>();
_container.Register(
Component.For<IInterface>().ImplementedBy<C1>(),
Component.For<IInterface>().ImplementedBy<C2>(),
Component.For<Root>().DependsOn(Dependency.OnComponent<IInterface, C2>())
);
var t = _container.Resolve<Root>();
}
I used a workaround with DependencyOnValue and created the delegate factory myself, but thats ugly:
Component.For<Root>().DependsOn(Dependency.OnValue<Func<IInterface>>((Func<IInterface>)(_ => new C2())
So am i doing something wrong ? Or is it a bug ? Or maybe its by design ? Is there a better way than the Dependency.OnValue ? Note: this example is verry simplified and sadly refactoring the classes is out of the question. Note2: the delgate (Func<IInterface>) in my case takes arguments, i just removed them because they are not neccesary for the example
version 4.0.30319 (i know its not the newest, but i work with what i have and if neccesary i can upgrade )
Issue Analytics
- State:
- Created 5 years ago
- Comments:21
Top GitHub Comments
I still think the whole problem starts here:
According to the docs here:
It is just a recommendation of mine that the code above throws an exception because the container is arbitrarily picking the first component registration(which is not necessarily what the user always means, and we really want clean code. Why have registrations that you probably don’t need because they are ignored?). This is default behaviour which as you correctly identified is not making it’s way through to invocations from the TypedFactoryInterceptor when you use DependendsOn. I would however expect the following registrations would not throw an exception:
What Worked
With the above in mind, I played around with a few scenario’s to see what does work.
Re-ordering worked:
Fallbacks worked:
Using factory method with named registrations worked:
Explicit factory registration with default worked:
Conclusion
I just question the time invested in fixing this API. There are already so many
good
ways you could do this. I am leaning towards deprecating the API altogether in favour of a slightly more explicit registration model. My two cents. Feel free to tell me what you think.Should throw an exception to make it more deterministic unless we are dealing with overrides or list resolvers. No?