1

给定一个程序集,其中我有一个SomeContext派生自DbContext并实现 interface的类ISomeContext,以及一个SomeService实现ISomeServiceinterface 的类,我将绑定应用程序的其余依赖项,如下所示:

kernel.Bind(t => t.FromThisAssembly()
                  .SelectAllClasses()
                  .Where(c => !c.Name.EndsWith("Context") && !c.Name.EndsWith("Service"))
                  .BindAllInterfaces());

然后,鉴于它SomeService具有构造函数注入的ISomeContext依赖项,使用Ninject.Extensions.NamedScope我可以定义一个命名范围,如下所示:

kernel.Bind<ISomeService>().To<SomeService>().DefinesNamedScope("ServiceScope");

然后当我说SomeContext生活在我刚刚创建的命名范围内时,如下所示:

kernel.Bind<ISomeContext>().To<SomeContext>().InNamedScope("ServiceScope");

我的理解是,通过这样做,每当一个实例SomeService被注入时,SomeContext它在其构造函数中接收到的实例只会在SomeService实例存在时存活 - 也就是说,当SomeService被垃圾收集时,SomeContext被处理并优雅地死亡。

...我有几个问题:

  • 这是确定实现类的正确方法IDisposable吗?
    • 如果不是,那么确定一次性类范围的正确方法是什么?
  • 如果SomeService被注入到另一个类中(事实证明它确实是!),那么其他类不是在某种程度上创建了上下文生存和死亡的范围吗?如果是这样,那么声明一个“命名范围”有什么用,如果它所做的只是为在垃圾收集时处理的内容命名?
    • 简而言之,上面的代码最终与完全不指定范围有何不同?

注意:这里与InRequestScope无关,我不是在谈论 Web 应用程序。该应用程序实际上是一个类库,当客户端 VB6 库调用它时,它就会组合起来;C# 代码作为全局实例存在于 VB6 库中,整个 C# 应用程序立即组成。如果只要 C# 应用程序的全局 VB6 实例存在,上下文/一次性用品就存在,那么我做错了 - 我希望我的连接尽可能短,所以我相信我不能注入像这样的上下文,我应该注入工厂,这些工厂会吐出一个只在需要时才存在的上下文,这将是注入该工厂的人的范围......我想我刚刚回答了一部分我的问题在这里......有吗?

4

1 回答 1

1
  • 不使用作用域,ninject 不会调用IDispose.Dispose()Context。
  • 上下文上的 .InParentScope() 确保在它被注入 ( SomeService) 的对象被垃圾收集时释放上下文
  • --> 当SomeServiceimplementsINotifyWhenDisposed时,上下文将在被释放后立即SomeService被释放。
  • .InNamed 范围适用于将 Context 的相同实例注入到对象树的多个对象中。

无作用域与命名作用域对象引用

另见http://www.planetgeek.ch/2010/12/08/how-to-use-the-additional-ninject-scopes-of-namedscope/

于 2013-09-26T12:05:08.863 回答