这个问题是更多的是“我该怎么办?”,而不是“我在做什么错?”。我有一个名为的查询处理器,它处理查询(认为CQRS)。该对象被注入到我的演示者中。 QueryProcessor需要使用内核来解析绑定。直接或通过工厂注入内核很容易。这样做不会导致内存泄漏是诀窍。Ninject工厂扩展和处理内存泄漏
我已经使用内存分析器验证过我的QueryProcessor对象没有被垃圾收集。这个类看起来是这样的:
public sealed class QueryProcessor : IQueryProcessor, IDisposable
{
private readonly IKernelFactory _container;
private bool _disposed;
public QueryProcessor(IKernelFactory container)
{
_container = container;
}
//[DebuggerStepThrough]
public TResult Process<TResult>(IQuery<TResult> query)
{
var handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResult));
dynamic handler = _container.RetrieveKernel().Get(handlerType);
return handler.Handle((dynamic)query);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (disposing && !_disposed)
{
// dispose of stuff here
_disposed = true;
}
}
}
public interface IKernelFactory
{
IKernel RetrieveKernel();
}
我的作文根是相当简单的。我正在使用Ninject的工厂扩展。
public void OnLoad(IKernel kernel)
{
// Auto-Register all the validators which are stored in the Service assembly.
AssemblyScanner.FindValidatorsInAssembly(_serviceAssembly).ForEach(
result => kernel.Bind(result.InterfaceType, result.ValidatorType)
);
ManualRegistrations(kernel);
kernel.Bind<IKernelFactory>().ToFactory();
AutoRegisterType(kernel, typeof(IQueryHandler<,>));
AutoRegisterType(kernel, typeof(ICommandHandler<>));
}
如上所述,注入正在工作,但它留下了内存泄漏。我该如何让Ninject内核在我的QueryProcessor中解析内容而不会导致泄漏?
感谢
更新 - 新问题
我试图通过创建一个新的模块,新的内核,从根组成的主内核单独解决这个问题。这些子内核将被创建并处理,其生命周期与QueryProcessors的生命周期相关联。我把它挂在主模块上:
kernel.Bind<IQueryProcessor>().ToMethod(ctx => new QueryProcessor(new StandardKernel(new ProcessorModule(_serviceAssembly)))).InTransientScope();
在内核第一次被处理之前它工作正常。但在那之后,我得到了以下错误消息:
Error loading Ninject component ICache
No such component has been registered in the kernel's component container.
Suggestions:
1) If you have created a custom subclass for KernelBase, ensure that you have properly
implemented the AddComponents() method.
2) Ensure that you have not removed the component from the container via a call to RemoveAll().
3) Ensure you have not accidentally created more than one kernel.
该死如果我这样做,该死如果我不...
你如何绑定QueryProcessor?谁在处理查询处理器? – BatteryBackupUnit
另请注意,如果没有内存压力,对于垃圾收集器*不收集对象*是完全合法的。等待,直到你没有对对象的引用,然后把它当作内存泄漏是*无效*。那么你有什么证据证明实际上存在内存泄漏?由于您使用了内存分析器,因此请向我们展示所有到“QueryProcessor”的GC根目录(应该收集但不是)的路径。 – BatteryBackupUnit
@BatteryBackupUnit QueryProcessor与kernel.bind .To ()绑定,它由Presenters在其各自的Dispose方法中处理。但是,我不能处理内核,因为它在其他地方是需要的。请注意,这不是一个Web项目,所以内核需要比HTTP请求/响应寿命更长。我会尝试从今晚的探查器获取一些数据。但它确实有一个强制GC的按钮,并且该按钮对所有其他第1代对象有效,这些对象在GC之后会从下一个内存快照中消失。使用此配置的 –
onefootswill