【发布时间】:2012-02-14 03:26:36
【问题描述】:
这与其他地方所述的模式相似,并详细说明了in this blog post。正如博客文章中所述,我使用 Windsor 2.5.4 进行了这项工作,但决定改用 Windsor 3。当我这样做时,我注意到应用程序的内存使用量会随着时间的推移而上升 - 我猜这将是组件没有发布。
对博文中的代码进行了一些修改,这可能导致行为不同。
这是我的 AutoRelease 拦截器(直接来自博文,这里是为了方便和懒惰;))
[Transient]
public class AutoReleaseHandlerInterceptor : IInterceptor
{
private static readonly MethodInfo Execute = typeof(IDocumentHandler).GetMethod("Process");
private readonly IKernel _kernel;
public AutoReleaseHandlerInterceptor(IKernel kernel)
{
_kernel = kernel;
}
public void Intercept(IInvocation invocation)
{
if (invocation.Method != Execute)
{
invocation.Proceed();
return;
}
try
{
invocation.Proceed();
}
finally
{
_kernel.ReleaseComponent(invocation.Proxy);
}
}
}
我与博文的一个偏差是类型化工厂使用的选择器:-
public class ProcessorSelector : DefaultTypedFactoryComponentSelector
{
protected override Func<IKernelInternal, IReleasePolicy, object> BuildFactoryComponent(MethodInfo method,
string componentName,
Type componentType,
IDictionary additionalArguments)
{
return new MyDocumentHandlerResolver(componentName,
componentType,
additionalArguments,
FallbackToResolveByTypeIfNameNotFound,
GetType()).Resolve;
}
protected override string GetComponentName(MethodInfo method, object[] arguments)
{
return null;
}
protected override Type GetComponentType(MethodInfo method, object[] arguments)
{
var message = arguments[0];
var handlerType = typeof(IDocumentHandler<>).MakeGenericType(message.GetType());
return handlerType;
}
}
可能值得注意的是我没有使用默认解析器。 (这也许就是问题所在……)。
public class MyDocumentHandlerResolver : TypedFactoryComponentResolver
{
public override object Resolve(IKernelInternal kernel, IReleasePolicy scope)
{
return kernel.Resolve(componentType, additionalArguments, scope);
}
}
(为简洁起见,我省略了 ctor - 没有发生什么特别的事情,它只是调用了基本 ctor)。
我这样做的原因是因为默认解析器会尝试按名称而不是按类型进行解析并且失败。在这种情况下,我知道我只需要按类型解析,所以我只是覆盖了 Resolve 方法。
最后的难题是安装程序。
container.AddFacility<TypedFactoryFacility>()
.Register(
Component.For<AutoReleaseHandlerInterceptor>(),
Component.For<ProcessorSelector>().ImplementedBy<ProcessorSelector>(),
Classes.FromAssemblyContaining<MessageHandler>()
.BasedOn(typeof(IDocumentHandler<>))
.WithService.Base()
.Configure(c => c.LifeStyle.Is(LifestyleType.Transient)),
Component.For<IDocumentHandlerFactory>()
.AsFactory(c => c.SelectedWith<ProcessorSelector>()));
单步执行代码,调用拦截器 并执行 finally 子句(例如,我没有弄错方法名称)。但是,组件似乎没有被释放(使用性能计数器显示了这一点。每次调用工厂的 create 方法都会将计数器增加一)。
到目前为止,我的解决方法是在我的工厂接口中添加一个 void Release(IDocumentHandler handler) 方法,然后在它执行 handler.Process() 方法后,它显式释放处理程序实例,这似乎是作业 - 性能计数器上升,处理完成后下降)。
这里是工厂:
public interface IDocumentHandlerFactory
{
IDocumentHandler GetHandlerForDocument(IDocument document);
void Release(IDocumentHandler handler);
}
这是我的使用方法:
IDocumentHandlerFactory handler = _documentHandlerFactory.GetHandlerForDocument(document);
handler.Process();
_documentHandlerFactory.Release(handler);
因此,明确地进行发布就不需要拦截器,但我真正的问题是,为什么发布之间的这种行为会有所不同?
【问题讨论】:
标签: castle-windsor typed-factory-facility