У меня есть API. NET Core 3.1, который может использовать RabbitMq или Azure Service Bus. Выбор будет определяться через параметр конфигурации. Поскольку конфигурация, которую нужно использовать, является решением среды выполнения, я sh буду использовать фабричный шаблон вместе с. NET инъекцией зависимостей ядра. Я нашел статью по адресу https://medium.com/@mailbox.viksharma / factory-pattern-using-built-in-dependency-injection-of- asp - net -core-f91bd3b58665 , но не могу заставить фабрику работать . Любая помощь будет принята с благодарностью.
Проблема возникает в классе Factory из-за IServiceProvider. Я получаю сообщение об ошибке System.NullReferenceException: ссылка на объект не установлена для экземпляра объекта. при попытке GetService.
Factory class
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)
{
....
}
}
ConfigureServices в 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
}
);
}
}