gpt4 book ai didi

c# - 如何反转/注入(inject)依赖 - MassTransit Consumer

转载 作者:行者123 更新时间:2023-11-30 20:28:24 27 4
gpt4 key购买 nike

我正在做一个项目,一切正常,但我有一个紧密耦合的依赖项,我不知道如何反转/注入(inject)。

问题出在我的 Consumer 类中,它将接收命令消息以启动一个进程,该进程是全局消息队列服务项目的一部分,例如MyCompany.MQ.Services,但对命令消息告诉它启动的进程具有紧密耦合的依赖性,例如:

public Task Consume(ConsumeContext<MyMessageInterface> context)
{
logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();

try
{
TightCoupleProcess tcp = new TightCoupleProcess(context);

logger.Information("{Blah}, {Blah}, {Blah}", context.Message.exampleVar1, context.Message.exampleVar2, context.Message.exampleVar3);

tcp.StartProcess();

return Task.CompletedTask;

}
catch (Exception ex)
{
return Task.FromException(ex);
}
}

Task Consume 是 MassTransit 的一部分,我无法修改 Consume 的签名,因为它实际上是 IConsumer 接口(interface)的实现公共(public)交通

我想我想要的是一种反转/注入(inject)该依赖关系的方法,以便我的全局 MQ.services 项目不依赖于调用它的项目。我想我对反转/注入(inject)有一些误解,但我不确定如何表达我的缺点。也许我想要的是不可能的。我知道我不能修改接口(interface)实现,但如果像下面这样的东西起作用我会很酷,但由于 Consume 是 MassTransit 接口(interface)的实现,我不认为我可以注入(inject)来 self 的调用类的匿名函数:

public Task Consume(ConsumeContext<MyMessageInterface> context, AnonFunc() func)
{
try
{
func(context)

logger.Information("{Blah}, {Blah}, {Blah}", context.Message.exampleVar1, context.Message.exampleVar2, context.Message.exampleVar3);

return Task.CompletedTask;

}
catch (Exception ex)
{
return Task.FromException(ex);
}
}

我已经通过使用反射并将此逻辑放在 MQ.Services 项目中来设法绕过其他依赖项,例如消息类型定义,这使我可以保留所有 TightCoupleProcess 处理 MQ.serives 项目之外的相关代码,例如:

    public void PublishMessage(object msg)
{
MethodInfo method = this.GetType().GetMethod("InvokePublish");
MethodInfo generic = method.MakeGenericMethod(msg.GetType());
generic.Invoke(this, new object[] { msg });
}

public void InvokePublish<T>(object msg)
{
Task.Run(async () =>
{
await busControl.Publish(msg);
}).Wait();


}

但我不能对 Consumer 应用类似的策略,因为我已经提到的限制以及我敢肯定的健康剂量的无知。

如果这是可能的,有人会指出我正确的方向吗?

更多信息:

项目:App.SubscriberConsole -> 引用 App.Services.Subscriber

项目:App.Services.Subscriber -> 引用 MyCompany.MQ.Services.Consumer

项目 MyCompany.MQ.Services.Consumer -> 引用 MassTransit -> 实现 MassTransit.IConsumer

最佳答案

我不确定您为什么考虑注入(inject) Consume 方法。方法签名来自接口(interface),您无法更改它。

您应该在消费者类构造函数中注入(inject)。考虑注入(inject)工厂委托(delegate)是正确的。

public class MyMessageConsumer : IConsumer<MyMessage>
{
private readonly Func<IConsumeContext<MyMessage>, TightCoupleProcess> factory;

public MyMessageConsumer(Func<IConsumeContext<MyMessage>, TightCoupleProcess> factory)
{
_factory = factory;
}

public Task Consume(ConsumeContext<MyMessage> context)
{
var tcp = _factory(context);
tcp.StartProcess();

return Task.CompletedTask;
}
}

然后你这样配置它:

Func<IConsumeContext<MyMessage>, TightCoupleProcess> factory = c => new TightCoupleProcess(c);
var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var host = cfg.Host(new Uri("rabbitmq://localhost/"), h =>
{
h.Username("guest");
h.Password("guest");
});

cfg.ReceiveEndpoint(host, "customer_update_queue", e =>
{
e.Consumer<MyMessageConsumer>(() => new MyMessageConsumer(factory));
});
});

您可以在端点 in the documentation 上找到更多消费者配置方法的重载.

还有一点。您对 Serilog 有严重的问题。您为您使用的每条消息创建记录器配置。这个不对。您应该在您的应用程序入口点创建记录器配置一次

然后,您要么注入(inject)您的记录器,要么使用全局 Log 对象,或者使用 MassTransit.SerilogIntegration 包并在您的消费者中使用 MassTransit 日志记录。

关于c# - 如何反转/注入(inject)依赖 - MassTransit Consumer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47584900/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com