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

本文关键字:魔术 字符串 枚举 实参 构造函数 | 更新日期: 2023-09-27 18:01:20

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

所以我需要传入静态argName像这样的
new ConstructorArgument("strVar","")

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

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

请指导我完成这个过程,或者建议我其他方法来实现这个目标。

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

like dynamics enum

没有现成的这样的结构。如果你真的讨厌字符串,你可以写一些表达式树lambda(即() => new Foo(strVal: "")() => new Foo("")),然而,a:是很多工作,b:如果容器提供了其他参数就不能很好地工作。

老实说,这不是什么问题,特别是因为命名参数意味着参数名应该被视为一种契约。在我看来,只要使用字符串。如果它让您担心,请确保您在单元测试中涵盖了该场景,这样您就可以及早发现它是否发生了变化。

我同意@Mark Gravell的立场,除了混淆器可以重命名非public因素的参数,所以该建议不适用于该特定情况,所以在某些情况下,您需要在参数上敲一个[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 ) );
    }
}

的工作方式如下:

public class StaticReflectionFacts
{
    public class X2
    {
    }
    public class X
    {
        public X( object param1, X2 param2 )
        {
        }
    }
    [Fact]
    static void DeriveNinjectConstructorArgumentFromPublic()
    {
        var newArg = StaticReflection<X>.CreateConstructorArgument( new X2() );
        Assert.Equal( "param2", newArg.Name );
    }
}

我已经实现了这个:

    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,但它是了解它是如何工作的一个很好的起点。