castle windsor ITypedFactoryComponentSelectors构造函数参数类型而不是名称

时间:2014-04-08 09:42:08

标签: c# castle-windsor factory

我正在使用外部库,我无法控制对象构造函数的命名约定。有各种构造函数可以通过参数类型进行区分。因此,我想覆盖类型工厂中的约定,以通过参数的确切名称进行检索,并使用类型。

e.g。

GenderTemplateViewModel CreateGenderTemplateViewModel();
GenderTemplateViewModel CreateGenderTemplateViewModel(GenderTemplateModel     genderTemplateModel); 
GenderTemplateViewModel CreateGenderTemplateViewModel(GenderTemplateModel     genderTemplateModel, string extraInfo); 

因此,我可以通过类型而不是参数名称来获取正确的构造函数吗? 即覆盖哪种方法以及如何

public class ParameterbyTypeNotNameTypedFactoryComponentSelector :    DefaultTypedFactoryComponentSelector
{
    protected override Type GetComponentType(MethodInfo method, object[] arguments)
    {

        return base.GetComponentType(method, arguments);
    }
    protected override string GetComponentName(MethodInfo method, object[] arguments)
    {

        return base.GetComponentName(method, arguments);
    }
    protected override IDictionary GetArguments(MethodInfo method, object[] arguments)
    {

        return base.GetArguments(method, arguments);
    }
}

1 个答案:

答案 0 :(得分:1)

您需要GetArguments()方法。以下应该有效:

public class ExtendedTypedFactoryComponentSelector : DefaultTypedFactoryComponentSelector
{
    protected override IDictionary GetArguments(MethodInfo method, object[] arguments)
    {
        if (arguments == null)
        {
            return null;
        }

        ParameterInfo[] parameters = method.GetParameters();
        Arguments arg = new Arguments(new IArgumentsComparer[0]);
        for (int i = 0; i < parameters.Length; i++)
        {
            if (arg.Contains(parameters[i].ParameterType))
            {
                if (this.isFunc(method.DeclaringType))
                {
                    throw new ArgumentException(string.Format("Factory delegate {0} has duplicated arguments of type {1}. Using generic purpose delegates with duplicated argument types is unsupported, because then it is not possible to match arguments properly. Use some custom delegate with meaningful argument names or interface based factory instead.", method.DeclaringType, parameters[i].ParameterType));
                }
            }
            else
            {
                arg.Add(parameters[i].ParameterType, arguments[i]);
            }
            arg.Add(parameters[i].Name, arguments[i]);
        }
        return arg;
    }

    private bool isFunc(Type type)
    {
        return ((type.FullName != null) && type.FullName.StartsWith("System.Func"));
    }
}

注意:这只是DefaultTypedFactoryComponentSelector原始实现的略有不同的版本。

希望这有帮助。