Castle.MicroKernel.Handlers.DefaultGenericHandler.GetClosedImplementationType C# (CSharp) Method

GetClosedImplementationType() private method

private GetClosedImplementationType ( CreationContext context, bool instanceRequired ) : Type
context CreationContext
instanceRequired bool
return System.Type
		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);
			}
		}