如何适应自我?

时间:2015-11-17 23:43:11

标签: c# entity-framework ninject ninject.web.mvc

我们有一个使用工作单元模式的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一样。

这是我们想要实现的目标图。

enter image description here

因此,A1的对象图完全独立于A2的对象图,服务D就像每个对象图中的单例一样。

那么,我们如何配置IUnitOfWork和/或IStore来使其工作? 感谢。

1 个答案:

答案 0 :(得分:0)

您始终需要使用lower or equal scope than its dependencies *。

来确定消费者的范围

例如,如果您在请求范围内绑定了上下文,则IUnitOfWork事物(我假设消耗IStore)应该绑定在请求范围或瞬态范围内。

IUnitOfWork的任何消费者也需要在请求范围或更低的范围内绑定(我想这是你缺少的一点,某些东西可能是某个地方的线程或单例范围)。

*瞬态范围是此规则的一个例外,因为它由消费者确定范围。 EG将被置于其注入物的范围的末端。