-
Notifications
You must be signed in to change notification settings - Fork 458
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrong c'tor get's choosed #136
Comments
@stffabi - I have been through this in detail: The ProblemThe problem is with this constructor: public class MyGenericUtilsImpl<T> : IMyUtils<T>
{
public MyGenericUtilsImpl(IMyHelper<T> aUtils)
{
Console.WriteLine("MyGenericUtilsImpl: ctor " + aUtils.GetType().Name);
}
} and how var lFixedHelperReg =
Component.For(typeof(IMyHelper<ArrayList>)).
ImplementedBy(typeof(MyArrayListFixedHelperImpl)); The constructor is requesting an Open Generic (meaning it is a more general type because there is no generic parameter). This technically does not match anything you have registered in the container(if this does not make sense because it resolves anyway, don't worry I will come back to this at the end). Your service registration has a higher specificity(or is in fact considered to be a new type) because it registers a Closed Generic (meaning it has a generic parameter type of ArrayList bound to IMyHelper`1). During the the resolution process the container To further demonstrate my explanation, I invite you to change the constructor on MyGenericUtilsImpl to use an ArrayList instead of T like so: public class MyGenericUtilsImpl<T> : IMyUtils<T> // <-- 2. Is not implied by consumers of this when picking constructors
{
public MyGenericUtilsImpl(IMyHelper<ArrayList> aUtils) // <-- 1. Inference of <T> here.
{
Console.WriteLine("MyGenericUtilsImpl: ctor " + aUtils.GetType().Name);
}
} You will notice this hits your expected constructor. You also identified another approach which was to open up the generic registration which then also satisfies the requested service type on // Commenting the following code in, let's the example run as expected.
//var lGenericHelperReg =
// Component.For(typeof(IMyHelper<>)).
// ImplementedBy(typeof(MyGenericHelperImpl<>)); This was the smoking gun that pointed me in in Why does it resolve if I remove the constructor or apply the [DoNotSelect] attribute?public class MyControl
{
[DoNotSelect] // <-- This attribute
public MyControl()
{
throw new ApplicationException("Should not be used.");
}
public MyControl(IMyUtils<ArrayList> aUtils)
{
Console.WriteLine("MyControl: ctor " + aUtils.GetType().Name);
}
} This is a good question. I am thinking some of these smarts have not been lifted up to the |
@stffabi - Good find! :) |
Merged, thanks heaps @Fir3pho3nixx, great work simplifying the test case. |
Accordingly to https://github.com/castleproject/Windsor/blob/master/docs/how-constructor-is-selected.md the constructor with the most satisfiable parameters gets picked.
In the following example, Windsor chooses the parameterless c'tor on MyControl although the c'tor with the parameter of type
IMyUtils<ArrayList>
can be resolved as proofed bylResolvedFixedHelper
Registering a generic type-unbound implementation for
IMyHelper<>
seems to fix the problem and the expected c'tor is called on MyControl.The text was updated successfully, but these errors were encountered: