private Type GetClosedImplementationType(CreationContext context, bool instanceRequired)
{
if (ComponentModel.Implementation == typeof(LateBoundComponent))
{
return context.RequestedType;
}
var genericArguments = GetGenericArguments(context);
try
{
return ComponentModel.Implementation.MakeGenericType(genericArguments);
}
catch (ArgumentNullException)
{
if (implementationMatchingStrategy == null)
{
// NOTE: if we're here something is badly screwed...
throw;
}
throw new HandlerException(
string.Format(
"Custom {0} ({1}) didn't select any generic parameters for implementation type of component '{2}'. This usually signifies bug in the {0}.",
typeof(IGenericImplementationMatchingStrategy).Name, implementationMatchingStrategy, ComponentModel.Name), ComponentModel.ComponentName);
}
catch (ArgumentException e)
{
// may throw in some cases when impl has generic constraints that service hasn't
if (instanceRequired == false)
{
return null;
}
// ok, let's do some investigation now what might have been the cause of the error
// there can be 3 reasons according to MSDN: http://msdn.microsoft.com/en-us/library/system.type.makegenerictype.aspx
var arguments = ComponentModel.Implementation.GetGenericArguments();
string message;
// 1.
if (arguments.Length > genericArguments.Length)
{
message = string.Format(
"Requested type {0} has {1} generic parameter(s), whereas component implementation type {2} requires {3}.{4}" +
"This means that Windsor does not have enough information to properly create that component for you.",
context.RequestedType,
context.GenericArguments.Length,
ComponentModel.Implementation,
arguments.Length,
Environment.NewLine);
if (implementationMatchingStrategy == null)
{
message += string.Format("{0}You can instruct Windsor which types it should use to close this generic component by supplying an implementation of {1}.{0}" +
"Please consult the documentation for examples of how to do that.",
Environment.NewLine,
typeof(IGenericImplementationMatchingStrategy).Name);
}
else
{
message += string.Format("{0}This is most likely a bug in the {1} implementation this component uses ({2}).{0}" +
"Please consult the documentation for examples of how to implement it properly.",
Environment.NewLine,
typeof(IGenericImplementationMatchingStrategy).Name,
implementationMatchingStrategy);
}
//"This is most likely a bug in your registration code."
throw new HandlerException(message, ComponentModel.ComponentName, e);
}
// 2.
var invalidArguments = genericArguments.Where(a => a.IsPointer || a.IsByRef || a == typeof(void)).Select(t => t.FullName).ToArray();
if (invalidArguments.Length > 0)
{
message = string.Format("The following types provided as generic parameters are not legal: {0}. This is most likely a bug in your code.",
string.Join(", ", invalidArguments));
throw new HandlerException(message, ComponentModel.ComponentName, e);
}
// 3. at this point we should be 99% sure we have arguments that don't satisfy generic constraints of out service.
throw new GenericHandlerTypeMismatchException(genericArguments, ComponentModel, this);
}
}