我有一个 .NET Core 3.1 API,可能使用 RabbitMq 或 Azure Service Bus。选择将通过配置参数确定。由于使用的配置是运行时决策,我希望使用工厂模式以及 .NET Core 的依赖注入。我在这篇文章中找到了一些信息,但无法使工厂运作。非常感谢您的任何帮助。
因为 IServiceProvider 的问题,工厂类出现错误。我收到了“System.NullReferenceException:对象引用未设置为对象实例”的错误提示,在尝试 GetService 时发生该错误。 工厂类
因为 IServiceProvider 的问题,工厂类出现错误。我收到了“System.NullReferenceException:对象引用未设置为对象实例”的错误提示,在尝试 GetService 时发生该错误。 工厂类
public class MessageServiceFactory
{
readonly IServiceProvider serviceProvider;
public MessageServiceFactory(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
public IMessagingService GetMessagingService()
{
var messageProvider = ConfigProvider.GetConfig("MessageService", "Messaging_Service");
switch(messageProvider)
{
case "AzureServiceBus": return (IMessagingService)serviceProvider.GetService(typeof(MassTransitAzureServiceBusMessagingService));
case "RabbitMq": return (IMessagingService)serviceProvider.GetService(typeof(MassTransitRabbitMqMessagingService));
default: throw new ArgumentException("Invalid message service");
};
}
}
服务接口
public interface IMessagingService
{
Task Publish(object payload);
}
RabbitMQ 具体实现
public class MassTransitRabbitMqMessagingService : IMessagingService
{
readonly IMassTransitRabbitMqTransport massTransitTransport;
public MassTransitRabbitMqMessagingService(IMassTransitRabbitMqTransport massTransitTransport)
{
//transport bus config already happens in massTransitTransport constructor
this.massTransitTransport = massTransitTransport;
}
public async Task Publish(object payload)
{
....
}
}
在 Startup.cs 中配置服务
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(Configuration);
services.AddScoped<IMassTransitRabbitMqTransport, MassTransitRabbitMqTransport>();
services.AddScoped<IMassTransitAzureServiceBusTransport, MassTransitAzureServiceBusTransport>();
services.AddScoped<MessageServiceFactory>();
services.AddScoped<IMessagingService, MassTransitAzureServiceBusMessagingService>(s => s.GetService<MassTransitAzureServiceBusMessagingService>());
services.AddScoped<IMessagingService, MassTransitRabbitMqMessagingService>(s => s.GetService<MassTransitRabbitMqMessagingService>());
services.AddControllers();
}
控制器
[ApiController]
[Route("api/[controller]")]
public class ListenerController : ControllerBase
{
readonly ILogger<ListenerController> logger;
readonly MessageServiceFactory messageFactory;
public ListenerController(
ILogger<ListenerController> logger,
MessageServiceFactory messageFactory)
{
this.logger = logger;
this.messageFactory = messageFactory;
}
[HttpPost]
public async Task<IActionResult> Post()
{
var payload = new
{
...
};
await messageFactory.GetMessagingService().Publish(payload);
return Ok(
new GDMSResponse()
{
ProcessedDate = DateTime.Now,
SuccessFlag = true
}
);
}
}
ConfigureServices
中决定使用哪个实现吗?或者说,你应该能够在不重启应用程序的情况下更改配置文件吗? - MichaelMassTransitAzureServiceBusMessagingService
/MassTransitRabbitMqMessagingService
本身添加为AddScoped
,而不是通过IMessagingService
接口。这可能是罪魁祸首吗? - orhtej2