构造函数实参枚举和魔术字符串
本文关键字:魔术 字符串 枚举 实参 构造函数 | 更新日期: 2023-09-27 18:01:20
我正在开发我的c# .net应用程序,并使用Ninject实现IoC/DI模式,现在Ninject有一个名为ConstructorArgument
的类,它需要两个参数(argName,argValue)。
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,但它是了解它是如何工作的一个很好的起点。