5

Ninjects ConstructorArgumentを使用する場合、特定のパラメーターに注入する正確な値を指定できます。この値をnullにできないのはなぜですか、またはどうすれば機能させることができますか?たぶんそれはあなたがやりたいことではないかもしれませんが、私はそれを私のユニットテストで使用したいと思います。例:

public class Ninja
{
    private readonly IWeapon _weapon;
    public Ninja(IWeapon weapon)
    {
        _weapon = weapon;
    }
}

public void SomeFunction()
{
    var kernel = new StandardKernel();
    var ninja = kernel.Get<Ninja>(new ConstructorArgument("weapon", null));
}
4

4 に答える 4

7

ソース(および、省略した再現によって取得したスタックトレース:P)を確認します。

これはConstructorArgument、通常の使用法(つまり、値型またはnull以外の参照型を渡す場合)とは異なるctorのオーバーロードにバインドしているためです。

回避策は、nullをオブジェクトにキャストすることです:-

var ninja = kernel.Get<Ninja>( new ConstructorArgument( "weapon", (object)null ) );

Ninject 2ソース:

public class ConstructorArgument : Parameter
{
    /// <summary>
    /// Initializes a new instance of the <see cref="ConstructorArgument"/> class.
    /// </summary>
    /// <param name="name">The name of the argument to override.</param>
    /// <param name="value">The value to inject into the property.</param>
    public ConstructorArgument(string name, object value) : base(name, value, false) { }

    /// <summary>
    /// Initializes a new instance of the <see cref="ConstructorArgument"/> class.
    /// </summary>
    /// <param name="name">The name of the argument to override.</param>
    /// <param name="valueCallback">The callback to invoke to get the value that should be injected.</param>
    public ConstructorArgument(string name, Func<IContext, object> valueCallback) : base(name, valueCallback, false) { }
}

再現:

public class ReproAndResolution
{
    public interface IWeapon
    {
    }

    public class Ninja
    {
        private readonly IWeapon _weapon;
        public Ninja( IWeapon weapon )
        {
            _weapon = weapon;
        }
    }

    [Fact]
    public void TestMethod()
    {
        var kernel = new StandardKernel();
        var ninja = kernel.Get<Ninja>( new ConstructorArgument( "weapon", (object)null ) );
    }
}

レッスン?最新のソースをダウンロードして見ないように気が狂うでしょう。素晴らしいコメント、すてきなクリーンなコードベース。そのヒント/提案をしてくれた@IanDavisにもう一度感謝します!

于 2010-04-19T12:59:16.650 に答える
3

Ninjectはわかりませんが、AFAIKコンストラクターインジェクションは一般的に必須の依存関係に使用されるため、このコンテキストではnullはほとんど意味がありません。依存関係が必須でない場合、タイプはデフォルトのコンストラクターを提供し、代わりにプロパティインジェクションを使用する必要があります。

この投稿は追加情報を提供します。

于 2010-04-19T12:41:45.803 に答える
3

ユニットテストで使用したい

単体テストにIOCコンテナを使用する必要はありません。コンテナを使用して、実行時にアプリケーションを相互に接続する必要があります。それ以上のことは何もしません。そしてそれが傷つき始めたら、あなたのクラスが手に負えなくなっていることを示す匂いがします(SRP違反?)

この場合、単体テストは次のようになります。

var ninja = new Ninja(null);

上記は正当なC#コードであり、単体テストにnull参照を渡すことは、依存関係を必要としない単体テスト領域の完全に有効な方法です。

于 2010-04-19T13:03:59.850 に答える
0

コンストラクター引数も値型である可能性があるため、これはおそらくサポートされていません。

于 2010-04-19T12:27:03.483 に答える