0

免責事項:私は一般的にNinjectとDIに非常に慣れていません。また、私はNinjectと結婚していません。これがWindsor、Unity、SourceMap、または他の何かでどのように機能するかを誰かが説明したいのであれば、私はすべての耳です。

タイプのオブジェクトの格納を処理する次のクラスがありますTArchived

public class Archiver<TArchived> where TArchived : class
{
    public Archiver(Func<string> getName, IStore<TArchived> storage, Func<TArchived> getInitialState);
}

のインスタンスが作成されると、から返された名前のインスタンスArchiverを検索しようとします。インスタンスがない場合は、から返されたデフォルトでインスタンスを作成します。storagegetName()getInitialState()

次のクラスはArchiver、アイテムのリストを格納するために使用します。ただし、そのアイテムのリストのサイズは変更されませんが、コンパイル時にはそのリストはわかりません

public class MyClass
{
    public class Item
    {
        public string Value { get; set; }
    }

    public MyClass(Archiver<Item[]> archiver)
    {
        Archiver = archiver;
    }

    public static Item[] GetInitialState(IEnumerable<string> values)
    {
        return values.Select(value => new Item { Value = value }).ToArray();
    }

    public Archiver<Item[]> Archiver { get; private set; }
}

私は次のようにNinjectを設定しました:

public class Tests
{
    private IKernel Ninject { get; set; }

    public Tests()
    {
        Ninject = new StandardKernel();
        Ninject.Bind<IStore<MyClass.Item[]>>().To<MemoryStore<MyClass.Item[]>>();

        Ninject.Bind<Archiver<MyClass.Item[]>>().To<Archiver<MyClass.Item[]>>()
            .WithConstructorArgument("getName", new Func<string>(() => "TEST"))
            .WithConstructorArgument("getInitialState", new Func<MyClass.Item[]>(MyClass.GetInitialState(/* what here? */)));
    }

    [Fact]
    public void Test()
    {
        // testing options
        var tests = new[] { "A", "B" };

        var myClass = Ninject.Get<MyClass>();
    }

    [Fact]
    public void Test_2()
    {
        // different testing options
        var tests = new[] { "A", "B", "C" };

        var myClass = Ninject.Get<MyClass>();
    }
}

しかし、私はgetInitialStateパラメータに何を入れるかについて混乱しています。によって保存されるアイテムのさまざまなリストが必要な場合は、さまざまなアイテムを関数MyClassに渡す必要があります。GetInitialState

4

3 に答える 3

1

いくつかの実験の後、これらは私が思いついた最良の解決策です. もっといい方法が見たいです。

[Fact]
public void Test()
{
    Ninject.Bind<Func<MyClass.Item[]>>().ToProvider<Func<MyClass.Item[]>>(new CallbackProvider<Func<MyClass.Item[]>>((ctx) => () => MyClass.GetInitialState(new[] { "A", "B" })));
    var myClass = Ninject.Get<MyClass>();
}

[Fact]
public void Test2()
{
    Ninject.Bind<Func<MyClass.Item[]>>().ToConstant<Func<MyClass.Item[]>>(() => MyClass.GetInitialState(new[] { "A", "B", "C" }));
    var myClass = Ninject.Get<MyClass>();
}
于 2012-08-21T18:56:57.733 に答える
0

私はあなたの質問の深さを掘り下げていませんが、あなたがこのようなものをより高いレベルで管理する方法として、名前付きスコープまたはそれに非常に近いものを探しているように思えます。そこから、トピックに関する@Remo Gloorのブログ投稿へのリンクをたどることをお勧めします(不足しているものはNamedScope拡張機能wiki:Dに追加します)。

于 2012-08-22T21:57:35.017 に答える
0

コンストラクターの引数をバインディングから引き出して、解決時に追加できます。したがって、次のバインディングを使用します。

Ninject.Bind<Archiver<MyClass.Item[]>>().To<Archiver<MyClass.Item[]>>()
    .WithConstructorArgument("getName", new Func<string>(() => "TEST"));

そして、これを各単体テストで使用し、必要に応じてgetInitialStateの値を変更します。

var myClass = Ninject.Get<MyClass>()
    .WithConstructorArgument("getInitialState", 
        new Func<MyClass.Item[]>(MyClass.GetInitialState(new string[] { "1", "2", "3" }))
    );
于 2012-08-21T17:35:44.247 に答える