How to configure Ninject to enter the correct instance depending on the previously entered instance

I cannot find the right words for my question, so I will let my code speak.

I have a repository:

class Repository { public Repository(DbContext ctx) { } } 

then I have the following bindings:

 Bind<IRepository>().To<Repository>(); Bind<DbContext>().To<UserStoreContext>().When... Bind<DbContext>().To<CentralStoreContext>().When... 

and then I have a class that should access

db <
 class Foo { public Repository(IRepository userRepo, [CentralStoreAttribute]IRepository centralRepo) { } } 

How do I configure two DbContext bindings DbContext that stores with the correct contexts (based on CentralStoreAttribute) are introduced into the Foo constructor?

+3
source share
4 answers

Instead of relying on attributes in the right places, I usually create several types that are actually just aliases. This is useful because with Ninject (and presumably other IoC containers) we query dependencies by type.

So, if you need to β€œrequest” a user repository compared to the central one, I would create types that look like this:

 interface IRepository { /* methods and properties */ } interface IUserRepository : IRepository {} interface ICentralRepository : IRepository {} class Foo { public Foo(IUserRepository userRepo, ICentralRepository centralRepo) { // assign to fields } } 

I prefer this because then Ninject does not expire at all in my application, it is more declarative, and I think it is easier to remember than any agreement based approach, like the one you are trying.

0
source

I tried this in proving the concept, but in the end went in a different direction.

 Bind<IRepository>().ToMethod(x => { var repositoryType = x.Kernel .Get<IConfigObject>() .SomeStringPropertyDenotingTheRepository; switch (repositoryType ) { case "1": return (IRepository)new Repository1(); default: return (IRepository)new Repository2(); } }).InRequestScope(); 

While it was working, I never found out if it was using a single instance of IObjectB or creating an instance of a new instance - it should be pretty easy to understand. I figured he called ToMethod every time I used the DI on IRepository - not tested again.

+1
source

Use the When(Func<IRequest, bool> condition) overload When(Func<IRequest, bool> condition) to check recursively if r.Target.IsDefined(typeof(TAttribute), false) true for a given request or one of its participants r.ParentRequest

+1
source
 Bind<IRepository>().To<Repository>(); Bind<DbContext>().To<CentralStoreContext>() .When( context => context.Target != null && context.Target.GetCustomAttributes( typeof( CentralStoreAttribute ) ) != null ); // make the general binding after the more specific one Bind<DbContext>().To<UserStoreContext>(); 
0
source

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


All Articles