4

IFooIBar、の 3 つのインターフェイスを考えてみましょうIBaz。また、それぞれの実装であるクラスFooBar、およびがあります。Baz

実装では、それぞれがインターフェースに依存しますIContainer。したがって、Foo(および同様にBarand Baz) の実装は次のようになります。

class Foo : IFoo
{
    private readonly IDependency Dependency;

    public Foo(IDependency dependency)
    {
           Dependency = dependency;
    }

    public void Execute()
    {
         Console.WriteLine("I'm using {0}", Dependency.Name);
    }
}

さらに、 、 、およびContainerのインスタンスを含むクラスがあるとします。IFooIBarIBaz

class Container : IContainer
{
    private readonly IFoo _Foo;
    private readonly IBar _Bar;
    private readonly IBaz _Baz;

    public Container(IFoo foo, IBar bar, IBaz baz)
    {
        _Foo = foo;
        _Bar = bar;
        _Baz = baz;
    }
}

このシナリオでは、実装クラスが、、に注入される制約Containerにバインドし、3 つすべてで同じになるようにしたいと考えています。手動の方法では、次のように実装できます。IContainerIDependencyIFooIBarIBaz

IDependency dependency = new Dependency();
IFoo foo = new Foo(dependency);
IBar bar = new Bar(dependency);
IBaz baz = new Baz(dependency);
IContainer container = new Container(foo, bar, baz);

Ninject内でこれを達成するにはどうすればよいですか?

注: 依存関係をネストする方法を尋ねているわけではありません。私の質問は、具体化されたサービス内のオブジェクトのコレクション間で特定の依存関係が同じであることをどのように保証できるかということです。

非常に明確にするために、標準形式の Ninject は次と同等のコードを生成することを理解しています。

IContainer container = new Container(new Foo(new Dependency()), new Bar(new Dependency()), new Baz(new Dependency()));

私はその振る舞いが好きではありません。Dependencyシングルトンとして作成することもできません。具体的には、これは、 に複数のリクエストがある場合GetService<IContainer>、Ninject 呼び出しは次の手動インジェクションと意味的に同等であることを意味します。

var dep1 = new Dependency();
var container1 = new IContainer(new Foo(dep1), new Bar(dep1), new Baz(dep1));

var dep2 = new Dependency();
var container2 = new IContainer(new Foo(dep2), new Bar(dep2), new Baz(dep2));
4

3 に答える 3

3

メソッドを使用ToConstantして、バインドする正確なインスタンスを指定します。Unbind別のインスタンスに再バインドするために使用できる機会がある場合:

        IKernel nKernel = new StandardKernel();

        nKernel.Bind<IFoo>().To<Foo>();
        nKernel.Bind<IBar>().To<Bar>();
        nKernel.Bind<IBaz>().To<Baz>();
        nKernel.Bind<IContainer>().To<Container>();

        nKernel.Bind<IDependency>().ToConstant(new Dependency());            

        Container c = nKernel.Get<Container>();
        //utilize the container...

        nKernel.Unbind<IDependency>();
        nKernel.Bind<IDependency>().ToConstant(new Dependency());

        c = nKernel.Get<Container>();
        //utilize the container...
于 2012-09-12T03:18:14.870 に答える
1

別の試みがあります:

public class Container : IContainer
{
    private IFoo _foo;
    private IBar _bar;
    private IBaz _baz;


    public Container(IContainerDependencies dependencies)
    {
        _foo = dependencies.Foo;
        _bar = dependencies.Bar;
        _baz = dependencies.Baz;
    }
}

public class ContainerDependencies : IContainerDependencies
{
    public ContainerDependencies(IFoo foo, IBar bar, IBaz baz)
    {
        Foo = foo;
        Bar = bar;
        Baz = baz;
    }

    public IFoo Foo { get; set; }
    public IBar Bar { get; set; }
    public IBaz Baz { get; set; }
}

public interface IContainerDependencies
{
    IFoo Foo { get; set; }
    IBar Bar { get; set; }
    IBaz Baz { get; set; }
}

それで:

var kernel = new StandardKernel();
kernel.Bind<IFoo>().To<Foo>();
kernel.Bind<IBar>().To<Bar>();
kernel.Bind<IBaz>().To<Baz>();
kernel.Bind<IContainerDependencies>().ToMethod(context =>
    {
        context.Kernel.Unbind<IDependency>();
        context.Kernel.Bind<IDependency>().ToConstant(new Dep());
        return context.Kernel.Get<ContainerDependencies>();
    });
 kernel.Bind<IContainer>().To<Container>();
于 2012-09-12T04:50:52.057 に答える
1

編集:

これはどう?

kernel.Bind<IContainer>().ToMethod(context =>
            {
                IDependency dependency = new Dep();
                IFoo foo = new Foo(dependency);
                IBar bar = new Bar(dependency);
                IBaz baz = new Baz(dependency);
                return new Container(foo, bar, baz);
            });
于 2012-09-12T03:40:21.037 に答える