构造函数参数枚举和魔术字符串

时间:2011-07-07 07:20:31

标签: c# .net reflection ninject

我正在使用我的c#.net应用程序并使用Ninject使用实现IoC / DI模式,现在Ninject有一个名为ConstructorArgument的类,它带有两个参数(argName,argValue)。

所以我需要传递像这样的静态argName

new ConstructorArgument("strVar","")

传递硬编码字符串似乎不是一个好选择。

所以我想使用构造函数参数的反射来创建类似动态枚举的东西,所以我不需要传递硬编码的字符串。

请指导我完成此过程或建议我实现此目的。

3 个答案:

答案 0 :(得分:3)

  

喜欢动态枚举

没有这样的结构可供使用。如果你真的讨厌字符串,你可以写一些表达式树lambda(即() => new Foo(strVal: "")() => new Foo(""),但是 - a:是很多工作,并且b:如果容器提供其他参数,将无法正常工作。

说实话,这有点不问题,特别是因为命名参数意味着参数名称应该被视为契约。 IMO,只需使用字符串。如果它让您担心,请确保在单元测试中涵盖场景,以便尽早发现它是否发生变化。

答案 1 :(得分:2)

我同意@Mark Gravell的立场,除了混淆器可以重命名非public ctors的参数,因此该建议不适用于该特定情况,因此在某些情况下,您需要敲击{ {1}}用于在某些情况下保留名称的参数。

但我已经建立了这样的废话,可以回答你的问题。请不要使用它,因为我后悔写它!

[Obfuscation]

其中的工作原理如下:

static class StaticReflection<TClass>
{
    static string PublicConstructorParameterName<TParameter>()
    {
        return typeof( TClass ).GetConstructors( BindingFlags.Public | BindingFlags.Instance ).Single().GetParameters().Where( param => param.ParameterType == typeof( TParameter ) ).Single().Name;
    }

    internal static ConstructorArgument CreateConstructorArgument<TParameter>( TParameter value )
    {
        return new ConstructorArgument( PublicConstructorParameterName<TParameter>(), value );
    }

    internal static ConstructorArgument CreateConstructorArgument<TParameter>( Func<IContext, TParameter> argumentResolver )
    {
        return new ConstructorArgument( PublicConstructorParameterName<TParameter>(), context => (object)argumentResolver( context ) );
    }
}

答案 2 :(得分:0)

我已经实现了这个:

    public string GiveConstuctorArgumentName(Type class, Type constructorArgument)
    {
       var cons = class.GetConstructors();

       foreach (var constructorInfo in cons)
       {
          foreach (var consParameter in constructorInfo.GetParameters())
          {
             if (consParameter.ParameterType == constructorArgument)
             {
                return consParameter.Name;
             }
          }
       }

       throw new InstanceNotFoundException();
    }

它没有LINQ,但它是了解其工作原理的良好开端。