[英]Castle Windsor scoped life style fails to register per scope
我正在使用一个允许在某些入口点进行拦截的框架。
框架范围不是Web请求,不是线程,不是瞬时的,类似于基于线程的东西,但是我看到了很多地方可以重用线程。
所以我需要一个自定义范围,在这里我说范围的起点和终点。
由于我有很多依赖关系,因此大多数依赖关系是在静态承包商中定义的,因为它们是无状态的。
我有一个依赖项,实际上需要在每个框架拦截中注入。
这是拦截方法,以及我如何进行注入(框架没有调用此方法)。 因此,我这里需要注入AppContext
并确保Castle始终为我解析正确的上下文(在范围内)
public void Execute(AppContext context)
{
using (var s = CastleContainer.Container.BeginScope())
{
CastleContainer.Container.Register(Component.For<AppContext>().LifestyleScoped().Instance(context));
var logic = CastleContainer.Container.Resolve<ICustomerLogic>();
// begin invocation
}
}
ICustomerLogic
有依赖于ICustomreDal
和ICustomreDal
具有依赖性AppContext
。
因此,当我解析Resolve<ICustomerLogic>()
我想确保ICustomreDal
具有当前的AppContext
。
ICustomerLogic
已注册为单例,而ICustomreDal已注册为瞬态。
第一个执行正常,第二个执行我收到错误:
无法注册AppContext。 已经有一个具有该名称的组件。 您是否要修改现有组件? 如果不是,请确保指定唯一名称。
城堡不应该进行范围分割,所以每个范围都有自己的依赖性吗?
我究竟做错了什么?
请注意,我们正在谈论每秒执行50次。
BeginScope与注册无关,仅与组件解析有关。 将确保在using语句结束时,释放(在必要时进行处置)在using语句中创建的,带有生活方式Scoped的任何组件。 它不会取消注册块中已注册的组件。 通常,在多个位置注册组件是一个坏主意。 仅在应用程序启动时注册组件。
我一直在努力地应对类似问题,最后使用这种解决方法时,我并不完全满意,但是如果有任何人有更好的解决方案,我很想听听。 根据您的情况,它看起来像这样:
在您的注册码中使用:
Component.For<ICustomerLogic>().ImplementedBy<CustomerLogic>().LifestyleScoped
Component.For<AppContext >().UsingFactoryMethod(() => (AppContext)Thread.GetNamedDataSlot("context")).LifestyleTransient() // or scoped
使您的执行功能适应:
public void Execute(AppContext context)
{
using (var s = CastleContainer.Container.BeginScope())
{
Thread.SetData(Thread.GetNamedDataSlot("context"), context);
var logic = CastleContainer.Container.Resolve<ICustomerLogic>();
Thread.SetData(Thread.GetNamedDataSlot("context"), null);
// begin invocation
}
}
祝好运,
Marwijn。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.