8

「強いネーミング」という言葉が適切かどうかはわかりませんが、やりたいことは次のとおりです。

現在、たとえば次のように ConstructorArgument を使用しています。

public class Ninja
{
    private readonly IWeapon _weapon;
    private readonly string _name;

    public Ninja(string name, IWeapon weapon)
    {
        _weapon = weapon;
        _name = name;
    }
    // ..more code..
}

public void SomeFunction()
{
    var kernel = new StandardKernel();
    kernel.Bind<IWeapon>().To<Sword>();
    var ninja = kernel.Get<Ninja>(new ConstructorArgument("name", "Lee"));
}

ここで、パラメーター「name」の名前を変更すると (たとえば、ReSharper を使用して)、ConstructorArgument が更新されず、Ninja の作成時にランタイム エラーが発生します。これを修正するには、ConstructorArgument を介してこのパラメーターを指定し、更新するすべての場所を手動で見つける必要があります。ダメです。テスト カバレッジが良好であっても、ある時点で失敗する運命にあります。名前の変更は安価な操作である必要があります。

パラメータの名前を変更すると更新されるように、代わりにパラメータを参照する方法はありますか?

4

3 に答える 3

5

あなたが本当に達成しようとしていることをもっと共有できれば、より良い答えが得られます。一般に、ConstructorArgument を渡すことに依存したくない場合は、それが助けになる場合があります。これは、所有していないコンポーネントの作成にパラメーター値を押し込む最後の手段である必要があります。リファクタリング活動中に willy nilly と名前が変更されました。したがって、通常のコードの場合、それをインターフェイスに保持して、物事を明確にし、名前に依存しないようにすることができれば、より良い.

今は例を掘り下げることはできませんが、静的反射と呼ばれるかなり一般的なイディオムがあります。提供された ConstructorArgument は、任意のコンストラクター全体でその名前の任意のパラメーターと一致する可能性があるため、このインスタンスでは静的なリフレクションは最適ではありません。

したがって、静的リフレクションでおそらく達成できる最高のものは、次のようなものです。

var ninja = ninject.Get<Ninja>( ParamNamesOf(()=>new Ninja( "dummy", "dummy" )).First() );

典型的な例は、インスタンスでアクセスされているプロパティの名前を抽出したい場合です。コンストラクター呼び出し式で動作する必要があるため、これは少し異なります。

ConstructorArgumentすでにそれを持っている適切なライブラリを見つけることについては、サーチャーの練習をしてください:D (しかし、とにかく、このアプローチよりも優先して使用しない、やりたいことを表現するより良い方法を見つけることをお勧めします.)

于 2010-04-14T12:30:15.160 に答える
4

既にお気づきのように、このアプローチは非常に壊れやすいため、避ける必要があります。コンストラクターの引数として名前を追加する必要がない設計を試してください。たとえば、これを行うことができます:

public class Ninja
{
    private readonly IWeapon _weapon;

    public Ninja(IWeapon weapon)
    {
        _weapon = weapon;
    }

    public string Name { get; set; }

    // ..more code..
}

public void SomeFunction()
{
    var kernel = new StandardKernel();
    kernel.Bind<IWeapon>().To<Sword>();
    var ninja = ninject.Get<Ninja>();
    ninja.Name = "Lee";
}

これが役立つことを願っています。

于 2010-04-14T12:03:39.577 に答える
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 はありませんが、その仕組みを理解するための良い出発点です。

于 2013-02-20T12:48:39.590 に答える