范围一次性用品

时间:2013-09-24 14:31:09

标签: c# ninject idisposable

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

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#app的全局VB6实例一样存在,那就是我做错了 - 我希望我的连接尽可能短暂,所以我相信我不能注入就像这样的上下文,我应该注入工厂,这些工厂吐出的环境只能在需要的时候生存下去,那将是那个工厂注入的范围...我想我刚回答了一部分我的问题在这里......我有吗?

1 个答案:

答案 0 :(得分:1)

  • 不使用范围,ninject不会在上下文中调用IDispose.Dispose()
  • .InParentScope()在上下文中确保当注入到(SomeService)的对象被垃圾收集时处理上下文
  • - &GT;当SomeService实施INotifyWhenDisposed时,上下文将在SomeService被处置后立即处理。
  • .InNamed范围适用于将Context的同一实例注入对象树的多个对象。

No Scope vs. Named Scope object references

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