我找不到合适的问题,所以我会让我的代码说出来。
我有存储库:
class Repository
{
public Repository(DbContext ctx)
{
}
}
然后我有这个绑定:
Bind<IRepository>().To<Repository>();
Bind<DbContext>().To<UserStoreContext>().When...
Bind<DbContext>().To<CentralStoreContext>().When...
然后我有类需要访问db的
class Foo
{
public Repository(IRepository userRepo, [CentralStoreAttribute]IRepository centralRepo)
{
}
}
我应该如何配置两个DbContext
绑定,以便将具有正确上下文的存储库(基于CentralStoreAttribute)注入到Foo构造函数中?
答案 0 :(得分:1)
我在概念证明中尝试了这一点,但最终走向了另一个方向。
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();
虽然它有效,但我从未弄清楚它是否正在使用我的IObjectB单例实例或实例化一个新实例 - 应该很容易弄明白。我认为每次我在IRepository上使用DI时都会调用ToMethod - 再次未经验证。
答案 1 :(得分:1)
使用When(Func<IRequest, bool> condition)
重载来递归检查,如果给定请求或其祖先之一r.Target.IsDefined(typeof(TAttribute), false)
为真r.ParentRequest
答案 2 :(得分:0)
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>();
答案 3 :(得分:0)
我不是依赖于正确位置的属性,而是创建几种实际上只是别名的类型。这很有用,因为对于Ninject(以及可能是其他IoC容器),我们要求通过类型名称来依赖它们。
因此,如果您需要能够“请求”一个用户存储库而不是一个中央存储库,我会创建类似于它的类型:
interface IRepository { /* methods and properties */ }
interface IUserRepository : IRepository {}
interface ICentralRepository : IRepository {}
class Foo
{
public Foo(IUserRepository userRepo, ICentralRepository centralRepo)
{
// assign to fields
}
}
我更喜欢这个,因为Ninject根本不会流入我的应用程序,它更具说明性,我认为它比任何基于约定的属性方法更容易记住,就像你正在尝试的那样。