我有一个使用kernel.Get<SomeClass>();
的控制台应用程序但是,SomeClass
依赖于SomeDisposableClass
。当SomeDisposableClass
被垃圾收集时,如何设置绑定以处置SomeClass
?我的MVC应用程序使用InRequestScope
并且效果很好,但似乎没有类似的控制台应用程序范围。
此处示例:
public class SomeClass {
public SomeClass(SomeDisposableClass c) {
this.C = c;
}
private SomeDisposableClass C { get; set; }
// ... Business Methods ... //
}
我的模块
kernel.Bind<ISomeClass>().To<SomeClass>().In???Scope()
我的控制台应用
public static void Main() {
SomeFunc();
SomeFunc();
Console.ReadLine();
}
public static void SomeFunc() {
ISomeClass someClass = kernel.Get<ISomeClass>();
// work
}
我希望在SomeDisposableClass
完成时(或调用垃圾收集器时)处理SomeFunc
。但我不确定使用哪种绑定范围。 InTransientScope
永远不会召唤处置。我是否只需要SomeClass
一次性并实现Dispose()
并使用using
声明将我的所有用法包装在控制台应用程序中?
答案 0 :(得分:8)
在Ninject2中,您可以通过以下方式执行此操作:
Bind<IService>().To<ServiceImpl>().InScope(ctx => ...);
例如,用于InRequestScope()
的回调是:
ctx => HttpContext.Current
由于HttpContext.Current
在每个Web请求上都设置为HttpContext
的新实例,因此每个请求只会激活一个服务实例,并且当请求结束时{{1 (最终)收集,实例将被停用。
您可以在控制台中使用静态变量来引用将控制生命周期的对象。
HttpContext
您可以将此注册为您的终身控制对象
public static object LifetimeController = new object();
每次要刷新对象时,都可以使用这样的方法
Bind<IService>().To<ServiceImpl>().InScope(ctx => LifetimeController);
答案 1 :(得分:0)
使用InTransientScope
- 然后Ninject容器将不会保留对该对象的任何引用。这样SomeClass
会在SomeFunc
结束时超出范围时进行GC。您需要做的就是让它的终结器处理SomeDisposableClass
实例:
public class SomeClass : IDisposable {
~SomeClass() {
if (this.C != null) this.C.Dispose();
}
}
以下是我的测试方法:
class Program
{
private static IKernel _kernel;
static void Main(string[] args)
{
_kernel = new StandardKernel();
_kernel.Bind<ISomeClass>().To<SomeClass>().InTransientScope();
while (true)
{
LifetimeController = new object();
SomeFunc();
Thread.Sleep(10);
}
}
public static void SomeFunc()
{
_kernel.Get<ISomeClass>();
}
public interface ISomeClass { }
public class SomeClass : ISomeClass
{
public SomeDisposableClass C = new SomeDisposableClass();
~SomeClass()
{
Console.WriteLine("{0} finalized", this);
C.Dispose();
}
}
public class SomeDisposableClass : IDisposable
{
private byte[] bytes = new byte[1000000];
public void Dispose()
{
Console.WriteLine("{0} disposed", this);
}
}
}