C# 将ConsumerContext注入到作用域对象中

C# 将ConsumerContext注入到作用域对象中,c#,.net,masstransit,C#,.net,Masstransit,我试图设置一些作用域对象,并将ConsumeContext注入其中,以便从实例中稍后使用它,以便发送一些消息 以下是我努力实现这一目标的方式 首先ScopedObject public class ScopedObject { public Guid ScopeId { get; set; } = NewId.NextGuid(); private ConsumeContext _context; public void SetContext(ConsumeConte

我试图设置一些作用域对象,并将
ConsumeContext
注入其中,以便从实例中稍后使用它,以便发送一些消息

以下是我努力实现这一目标的方式

首先
ScopedObject

public class ScopedObject
{
    public Guid ScopeId { get; set; } = NewId.NextGuid();

    private ConsumeContext _context;

    public void SetContext(ConsumeContext context)
    {
        _context = context;
    }

    public Task DoSomeStaff()
    {
        if (_context == null)
            throw new NullReferenceException(nameof(_context));

        //  publish message to bus using _context here... 

        return Task.CompletedTask;
    }
}
然后我准备了
InjectContextFilter
,它只解析
ScopedObject
并将
ConsumeContext
注入其中

public class InjectContextFilter : IFilter<ConsumeContext>
{
    private IServiceProvider _container;

    public InjectContextFilter(IServiceProvider container)
    {
        _container = container;
    }

    public async Task Send(ConsumeContext context, IPipe<ConsumeContext> next)
    {
        try
        {
            var scoped = _container.GetRequiredService<ScopedObject>();

            if (scoped != null)
            {
                scoped.SetContext(context);
            }

            await next.Send(context).ConfigureAwait(false);
        }
        catch (Exception)
        {
            throw;
        }
    }

    public void Probe(ProbeContext context)
    {
        var scope = context.CreateFilterScope("cqrslite");
    }
}
但实际上,
\u上下文
空的
。之所以发生这种情况,是因为在
ScopeConsumerFactory
中创建作用域之前触发了我的
InjectContextFilter
,因此,我在consumer中使用的作用域之外进行了注入

我的问题是如何在
ScopeConsumerFactory
之后应用InjectContextFilter?或者如何以任何其他方式将
ConsumeContex
注入作用域对象

演示代码可用

解决方案


工作演示是

如果您能够弄清楚如何在创建范围时将注册添加到范围中,那么整个问题都会解决,因为ConsumeContext可以在范围内注册,就像Autofac和StructureMap一样。简单回答您的问题,您需要在
ConsumerConsumeContext
上设置一个过滤器,而不仅仅是
ConsumeContext
。好的,我可以设置过滤器
IFilter
和规范
iIPpeSpecification
,但无法找到如何获取
iIPpeConfigurator
配置程序以应用过滤器。你能告诉我怎么做吗?我不能理解你的要求。如果_scoped.DoSomeStaff在消费操作之前或之后工作,则可以实现IConsumeObserver。如果您的_scoped.DoSomeStaff正在执行消费操作,则可能是您的业务代码和消费上下文对象为DoSomeStaff函数传递了一个参数。你能解释一下你的业务需求吗?如果我了解您的需要,我想尝试帮助。@AdemCatamak,这不是关于业务代码的问题。如何正确地将
ConsumeContext
注入任何作用域对象,以便稍后在实例中使用它,这是一个问题<代码>\u scoped.DoSomeStaff()只是一个示例。。。它与任何特定的项目都没有关系。我不想将
consumercontext
作为参数传递到
\u scoped.DoSomeStaff()
。如果这个
DoSomeStaff()
方法是接口实现,而我不能更改符号怎么办?谢谢@ChrisPatterson,我想我已经成功了!
        var services = new ServiceCollection();

        services.AddScoped<ScopedObject>();

        services.AddMassTransit(x =>
        {
            x.AddConsumer<DoSomeWorkConsumer>();
        });

        services.AddSingleton(context => Bus.Factory.CreateUsingRabbitMq(x =>
        {
            IRabbitMqHost host = x.Host(new Uri("rabbitmq://guest:guest@localhost:5672/test"), h => { });

            x.ReceiveEndpoint(host, $"receiver_queue", e =>
            {
                e.UseContextInjection(container);

                e.LoadFrom(container);
            });

            x.UseSerilog();
        }));

        container = services.BuildServiceProvider();

        var busControl = container.GetRequiredService<IBusControl>();
public class DoSomeWorkConsumer : IConsumer<DoSomeWork>
{
    private ScopedObject _scoped;

    public DoSomeWorkConsumer(ScopedObject scoped)
    {
        _scoped = scoped ?? throw new ArgumentNullException(nameof(scoped));
    }

    public async Task Consume(ConsumeContext<DoSomeWork> context)
    {
        await _scoped.DoSomeStaff();
    }
}