温莎城堡范围的生活方式无法按范围注册

本文关键字:范围 注册 城堡 生活方式 | 更新日期: 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
    }
}

ICustomerLogicICustomreDal有依赖性,ICustomreDalAppContext有依赖性。

因此,当我解决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
    }
} 

好运,

马尔维恩。