2011-07-07 14 views
3

私はC#.netアプリケーションで作業しており、Ninjectを使用してIoC/DIパターンを実装しています。Ninjectには2つの引数(argName、argValue)を取るConstructorArgumentというクラスがあります。コンストラクタ引数EnumsとMagic Strings

だから私は、静的なargnameのを渡す必要がハードコードされた文字列を渡すこの

new ConstructorArgument("strVar","") 

のようなものは良いオプションのように思えるしません。

私はダイナミクス列挙型のようなものをコンストラクタ引数のためのリフレクションを使用して作成したいので、ハードコードされた文字列を渡す必要はありません。

これを達成するには、このプロセスを案内してください。

答えて

3

ダイナミクス列挙型

のような容易に利用可能なような構築物はありません。 本当にの文字列を嫌うなら、表現木のラムダを書くことができます(つまり、() => new Foo(strVal: "")または() => new Foo("")ですが、a:は多くの作業であり、b:は他のパラメータがあるとうまく動作しません

正直言って、これは特に問題ではありません。特に名前付き引数は、パラメータ名を契約として扱う必要があることを意味しています。

2

私は@ 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); 
    } 
} 
0

私はこれをimlementedている:LINQのない

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(); 
    } 

そのが、その良いスタートポイントはどのようにその動作を理解しています。

関連する問題