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();
}
}