How to relate the same dependency to many dependents in Ninject?

Suppose I have three interfaces: IFoo , IBar , IBaz . I also have the Foo , Bar and Baz classes, which are respective implementations.

In implementations, each depends on the IContainer interface. So, for Foo (and similarly for Bar and Baz ), the implementation can read:

 class Foo : IFoo { private readonly IDependency Dependency; public Foo(IDependency dependency) { Dependency = dependency; } public void Execute() { Console.WriteLine("I'm using {0}", Dependency.Name); } } 

Also, let's say I have a Container class that contains instances of IFoo , IBar and IBaz :

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

In this scenario, I would like the Container implementation class to bind to IContainer with a constraint that the IDependency that is introduced in IFoo , IBar and IBaz will be the same for all three. In manual mode, I could implement it as:

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

How can I achieve this in Ninject?

Note. I am not asking how to make nested dependencies. My question is how can I guarantee that the given dependency is the same among the collection of objects in the materialized service.

To be extremely explicit, I understand that the standard Ninject form in it will generate code equivalent to the following:

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

I would not like this behavior. I cannot create Dependency as a singleton. In particular, this means that if I have multiple requests to GetService<IContainer> , Ninject calls should be semantically equivalent to the following manual injection:

 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
source share
3 answers

Use the ToConstant method to specify the exact instance to bind. If possible, you can use Unbind to re-bind to another instance:

  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... 
+3
source

EDIT:

How about this?

 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); }); 
+1
source

Here's another try:

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

Then:

 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>(); 
+1
source

Source: https://habr.com/ru/post/1433693/


All Articles