繁体   English   中英

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

[英]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有依赖于ICustomreDalICustomreDal具有依赖性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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM