我们有一个使用工作单元模式的Web服务。工作单元模式需要在几个地方使用相同的DbContext
。所以我们的第一个想法是将dbContext
范围限定在请求范围内,如下所示:
kernel.Bind<IStore>().ToConstructor<TestContext>(_ => new TestContext(Env.DbServerInstance, databaseName)).InRequestScope();
kernel.Bind<IUnitOfWork>().To<DbContextUnitOfWork>();
哪个工作得很好,直到我们需要在同一个Request Scope中使用两个Unit-of-Work对象。行动!我们收到一条错误,指出已经处理了DbContext。
InRequestScope
几乎有效,因此我们认为我们需要从dbContext
移动范围规则,并将IUnitOfWork
对象应用于某种类型的范围规则。这是我们目前的尝试:
kernel.Bind<IStore>().ToConstructor<TestContext>(_ => new TestContext(Env.DbServerInstance, databaseName));
kernel.Bind<IUnitOfWork>().To<DbContextUnitOfWork>().InScope(ctx =>
{
return ctx.???;
});
但是我们如何从ctx上下文对象访问实例化的DbContextUnitOfWork?我们可以访问DbContextUnitOfWork
类型(来自ctx.Request.Service
),但这似乎对我们没有帮助。换句话说,我想要这样的事情:
kernel.Bind<IUnitOfWork>().To<DbContextUnitOfWork>().InSelfScope();
或者有没有更好的方法来实现我们想要的结果呢?
更新
@Luke McGregor - 是的,IUnitOfWork
使用了IStore
界面。我还读到了你建议的Captive Dependency - 谢谢。但是,在我们的示例中,IUnitOfWork
是对象图的根节点,我们只需要每个IStore
的{{1}} 每个实例的单个实例
例如:假设UnitOfWork(称为服务A)依赖于服务B和C,这两个服务需要一个IStore(服务D)然后服务B和C 必须共享相同的服务服务实例D.(好像服务D是服务A的单例。)因此,如果我创建了两个UnitOfWork实例(A1和A2),那么系统应该只包含两个服务D实例(即D1)和D2)。
此外,当处理A1时,它的整个对象图也被处理掉,与A2一样。
这是我们想要实现的目标图。
因此,A1的对象图完全独立于A2的对象图,服务D就像每个对象图中的单例一样。
那么,我们如何配置IUnitOfWork和/或IStore来使其工作? 感谢。
答案 0 :(得分:0)
您始终需要使用lower or equal scope than its dependencies *。
来确定消费者的范围例如,如果您在请求范围内绑定了上下文,则IUnitOfWork事物(我假设消耗IStore)应该绑定在请求范围或瞬态范围内。
IUnitOfWork的任何消费者也需要在请求范围或更低的范围内绑定(我想这是你缺少的一点,某些东西可能是某个地方的线程或单例范围)。
*瞬态范围是此规则的一个例外,因为它由消费者确定范围。 EG将被置于其注入物的范围的末端。