温莎城堡范围的生活方式无法按范围注册
本文关键字:范围 注册 城堡 生活方式 | 更新日期: 2023-09-27 18:19:29
我正在使用一个框架,允许我拦截一些入口点。
框架范围不是 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 语句结束时被释放(必要时释放(。它不会取消注册在块中注册的组件。通常,在多个位置注册组件是一个坏主意。仅在应用程序启动时注册组件。
我一直在为类似的东西而苦苦挣扎,最后使用了这个解决方法,我并不完全满意,但如果有人有更好的解决方案,我很想听听。适应您的情况,它看起来像这样:
在您的注册码中使用:
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
}
}
好运,
马尔维恩。