C# 简单注入器,.NET Core 3.1,上下文对象的生存期短

C# 简单注入器,.NET Core 3.1,上下文对象的生存期短,c#,dependency-injection,simple-injector,C#,Dependency Injection,Simple Injector,我正在尝试将通过控制器接收的correlationId传递给我的IEventDispatcher,我希望在EventHandler处理完这个保存correlationId的对象后,立即将其释放 另外,我正在收听ServiceBus队列和主题,我还有IEventDispatcher的实例,我想在那里应用相同的逻辑 我在控制器中注入EventDispatcher,在控制器中设置我希望在EventHandler中访问的内部上下文,但不是通过直接传递上下文,而是通过DI访问上下文 public clas

我正在尝试将通过控制器接收的correlationId传递给我的IEventDispatcher,我希望在EventHandler处理完这个保存correlationId的对象后,立即将其释放

另外,我正在收听ServiceBus队列和主题,我还有IEventDispatcher的实例,我想在那里应用相同的逻辑

我在控制器中注入EventDispatcher,在控制器中设置我希望在EventHandler中访问的内部上下文,但不是通过直接传递上下文,而是通过DI访问上下文

public class CommandController : ControllerBase
{
    private readonly IEventDispatcher eventDispatcher;

    public CommandController(IEventDispatcher eventDispatcher)
    {
        this.eventDispatcher = eventDispatcher;
    }

    [HttpPost]
    public async Task<IActionResult> Post([FromBody]TAction action)
    {
        try
        {
            // I want this context to be disposed after handler 
            // that is called inside of eventDispatcher is done with execution
            var context = new HttpRequestContext(HttpContext); 

            await eventDispatcher.Dispatch<TAction>((TAction)action, context);
            return Ok();
        } catch (Exception e)
        {
            return BadRequest((new BadExceptionResult { Error = e.Message }));
        }
    }
}    
这里是EventDispatcher的样子

public class EventDispatcher : IEventDispatcher
{
    Container container;

    public EventDispatcher(Container container)
    {
        this.container = container;
    }

    public async Task Dispatch<TAction>(TAction action, IContext context)
    {
        using (AsyncScopedLifestyle.BeginScope(container))
        {
            // this is registered in `ConfigureServices` before  
            var handler = container.GetInstance(IEventHandler<TAction>);
        }
    }
}    
正如您所看到的,我使用AsyncScopedLifestyle.BeginScopecontainer,但在处理程序的构造函数中,我从未注入上下文对象,它总是空的。

您可以将IContext存储在范围内的组件中,例如范围开始处的RequestContextRegistrator。例如:

public async Task Dispatch<TAction>(TAction action, IContext context)
{
    using (AsyncScopedLifestyle.BeginScope(container))
    {
        container.GetInstance<IContextProvider>().SetContext(context);

        var handler = container.GetInstance<IEventHandler<TAction>>();
        await handler.Handle(action);
    }
}
不要忘记将IContextProvider实现注册为作用域


这种在对象图中存储状态的方法称为。

我实际上有这样的实现。结果证明RequestContextRegistrator实现不正确,并且没有存储上下文。无论如何,谢谢你的详细回答。
public class EventDispatcher : IEventDispatcher
{
    Container container;

    public EventDispatcher(Container container)
    {
        this.container = container;
    }

    public async Task Dispatch<TAction>(TAction action, IContext context)
    {
        using (AsyncScopedLifestyle.BeginScope(container))
        {
            // this is registered in `ConfigureServices` before  
            var handler = container.GetInstance(IEventHandler<TAction>);
        }
    }
}    
public async Task Dispatch<TAction>(TAction action, IContext context)
{
    using (AsyncScopedLifestyle.BeginScope(container))
    {
        container.GetInstance<IContextProvider>().SetContext(context);

        var handler = container.GetInstance<IEventHandler<TAction>>();
        await handler.Handle(action);
    }
}
public class OrderShippedHandler : IEventHandler<OrderShipped>
{
    private readonly IContextProvider provider;

    public OrderShippedHandler(IContextProvider provider) => this.provider = provider;

    public async Task Handle(OrderShipped e)
    {
        IContext context = this.provider.Context;
    }
}