简体   繁体   English

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

[英]Castle Windsor scoped life style fails to register per scope

I am using a framework that allow me to intercept in some entry points. 我正在使用一个允许在某些入口点进行拦截的框架。
The framework scope is not Web Request, not thread and not transient, its something like thread based, but i saw a lot of places with thread reuse. 框架范围不是Web请求,不是线程,不是瞬时的,类似于基于线程的东西,但是我看到了很多地方可以重用线程。
So i need a custom scope, where i say where to start and where to end the scope. 所以我需要一个自定义范围,在这里我说范围的起点和终点。
Since I have a lot of dependencies, most of them are defined in static contractor, because they are stateless. 由于我有很多依赖关系,因此大多数依赖关系是在静态承包商中定义的,因为它们是无状态的。
I have one dependency that actually need to be injected on every framework interception. 我有一个依赖项,实际上需要在每个框架拦截中注入。

This is the interception method, and how I do the injection (I am not calling this method, the framework does). 这是拦截方法,以及我如何进行注入(框架没有调用此方法)。 So what i need here is to inject the AppContext and make sure that Castle always resolve me the correct context (within the scope) 因此,我这里需要注入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 has dependency in ICustomreDal and ICustomreDal has dependency in AppContext . ICustomerLogic有依赖于ICustomreDalICustomreDal具有依赖性AppContext

So when I resolve Resolve<ICustomerLogic>() I want to be sure that ICustomreDal has the current AppContext . 因此,当我解析Resolve<ICustomerLogic>()我想确保ICustomreDal具有当前的AppContext

ICustomerLogic and registered as singleton, and ICustomreDal registered as transient. ICustomerLogic已注册为单例,而ICustomreDal已注册为瞬态。

The first execution works fine, the second execution I get the error: 第一个执行正常,第二个执行我收到错误:

AppContext could not be registered. 无法注册AppContext。 There is already a component with that name. 已经有一个具有该名称的组件。 Did you want to modify the existing component instead? 您是否要修改现有组件? If not, make sure you specify a unique name. 如果不是,请确保指定唯一名称。

Isn't castle suppose to do the scope segmentation so each scope has its own dependencies? 城堡不应该进行范围分割,所以每个范围都有自己的依赖性吗?
What am I doing wrong? 我究竟做错了什么?

Please note that we are talking about 50 executions in a second. 请注意,我们正在谈论每秒执行50次。

The BeginScope is not about registration, it is only about component resolving. BeginScope与注册无关,仅与组件解析有关。 It will make sure that any component that is created within the using statment, with lifestyle Scoped gets released (disposed if necessary) when the using statements end. 将确保在using语句结束时,释放(在必要时进行处置)在using语句中创建的,带有生活方式Scoped的任何组件。 It does not unregister components that are registered in the block. 它不会取消注册块中已注册的组件。 In general it is a bad idea to register your components in multiple places. 通常,在多个位置注册组件是一个坏主意。 Only register components at the startup of your application. 仅在应用程序启动时注册组件。

I've been struggling a lot with something similair and finally used this workaround with I was not totally happy with but if there is anyone with a better solution I would love to hear. 我一直在努力地应对类似问题,最后使用这种解决方法时,我并不完全满意,但是如果有任何人有更好的解决方案,我很想听听。 Adapted to your situation it would look something like this: 根据您的情况,它看起来像这样:

in your registration code use: 在您的注册码中使用:

Component.For<ICustomerLogic>().ImplementedBy<CustomerLogic>().LifestyleScoped
Component.For<AppContext >().UsingFactoryMethod(() => (AppContext)Thread.GetNamedDataSlot("context")).LifestyleTransient() // or scoped

adapt your Execute function to: 使您的执行功能适应:

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
    }
} 

Goodluck, 祝好运,

Marwijn. Marwijn。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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