问题
I can't find right words for my question so i will let my code speak instead.
I have Repository:
class Repository
{
public Repository(DbContext ctx)
{
}
}
then i have this bindings:
Bind<IRepository>().To<Repository>();
Bind<DbContext>().To<UserStoreContext>().When...
Bind<DbContext>().To<CentralStoreContext>().When...
and then i have class that needs to access both db's
class Foo
{
public Repository(IRepository userRepo, [CentralStoreAttribute]IRepository centralRepo)
{
}
}
How should i configure two DbContext
bindings so that repositories with right contexts (based on CentralStoreAttribute) would be injected into Foo constructor?
回答1:
Rather than relying on attributes in the right places, I usually create several types that are effectively just aliases. This is useful since with Ninject (and presumably other IoC containers) we're asking for dependencies by their type-name.
So if you need to be able to "request" a user repository vs a central one, I would create types that alias it 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 doesn't bleed into my app at all, it's more declarative, and I think it's simpler to remember than any convention based attribute approach like the one you're trying.
回答2:
I tried this in a proof of concept but eventually 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 worked, I never figured out if it was using my singleton instance of IObjectB or instantiating a new instance - should be pretty easy to figure out though. I figured it was calling ToMethod every time I used DI on IRepository - again not verified.
回答3:
Use the When(Func<IRequest, bool> condition)
overload to check recursivly if r.Target.IsDefined(typeof(TAttribute), false)
is true for the given request or one of its anchestors r.ParentRequest
回答4:
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>();
来源:https://stackoverflow.com/questions/6373122/how-to-configure-ninject-so-that-it-would-inject-right-instance-depending-on-pre