在Web应用程序中存储Ninject IKernel的位置在哪里?

6

我对IOC一般不太了解,有些困惑,希望你能帮我澄清疑问。我有一个Web Forms应用程序,想要创建一个模块来定义一些绑定关系。这些绑定关系将用于将仓储库注入到我的业务管理器类中,从而使我能够对业务管理器进行单元测试。此外,我还想使用容器将Entity Framework上下文注入到我的仓储库中,以便它们在每个HTTP请求期间共享相同的上下文。所以,我想知道:

  1. 我知道需要一个相同的内核实例来管理对象的创建和生命周期。例如,如果我想要一个每个HTTP请求类型场景,我需要在此期间保持内核实例的可用性。那如果我需要一个单例?那么它必须以某种方式作用于应用程序范围。那么我应该在哪里存储IKernel实例?看起来我可能想把它作为Global.asax文件中的静态变量存储,这样做正确吗?线程安全是否值得关注?

  2. 由于我正在使用Bind<>来定义我的绑定关系,当我不应该从UI层引用我的数据访问层时,我该如何在Web / UI层中进行定义?我的引用看起来像.Web --> .Business --> DataAccess。似乎我想告诉内核“嘿,管理我的数据访问实例,但不要在编译时引用它们。”像这样的绑定:


    // 任何请求AdventureWorksEntities实例的对象都将获得一个每个请求的实例
    Bind<AdventureWorksEntities>().ToSelf().InRequestScope();

感觉我可能方法不对,谢谢您。


https://dev59.com/2HRC5IYBdhLWcg3wP-Zh - Mauricio Scheffer
2个回答

1

这真的取决于您的 Web 应用程序的复杂性。

听起来您有一个业务和数据访问层;我个人会有一个“基础设施”层,我会在其中存储我的 DI 存储库和辅助类。


谢谢John,我认为你的建议确实是避免层之间耦合的唯一方法。我没有使用过其他容器,但我认为如果配置是基于XML的,这种情况本可以避免,这意味着容器会在运行时解析DLLs。 - e36M3

1

关于第一部分,请查看Ninject.Web扩展 - 它在应用程序级别保留了一个内核。您还可以在其中管理其他寿命较短的资源。

此外,可以在这里查看有关EF和L2S DataContext管理方面的问题和示例,涉及到Ninject和DI(在过去几周中已经出现)。

更新:同一OP的另一个问题的答案更具体(有一个KernelContainer类,带有.Inject(object).Kernel


Ruben,我研究了一下Ninject.Web,它似乎就是我一直在寻找的东西。我猜测这个扩展利用了某种“全局”静态内核引用,在本质上实现了我自己通过将其作为Global.asax的静态属性来完成的操作。然而,走Ninject.Web这条路,我不需要担心线程安全问题,因为我相信他们已经处理好了这个问题。 - e36M3
@e36M3 酷炫的用户名/车型(我是BH5 Blitzen :D)。你已经有了它,减去了“静态”推断 - 每个HttpApplication只有一个(可以有>1个进程和/或AppDomain),可能略有不同。确保查看那些其他文章 - 你需要在处理流程的适当时刻提交你的DB工作,而不是期望Ninject通过IDisposable等在正确的时间自动完成 - Ninject会Dispose,但是异步完成 - 不一定在请求处理期间。 - Ruben Bartelink
谢谢Ruben,我会再深入研究一下。我知道肯定有一种方法可以自动提交Entity Framework上下文(类似于NHibernate),我会浏览以前的帖子,看看能否找到类似的东西。目前,我将最后一个业务管理器放在“事务”中,负责调用SaveChanges方法。再次感谢。 - e36M3
@e36M3:在程序控制下明确地拥有这样的东西没有任何问题(尽管显然要以某种方式保持DRY - 有些人通过标准调用和/或重试策略来实现,而其他人则会进行AOP和其他程度不同的过度工程:D)。 - Ruben Bartelink

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接