Настройка внедрения зависимостей в Service Fabric с использованием стандартного контейнера ASP.NET Core DI
Я хотел бы использовать контейнер DI по умолчанию в ASP.NET Core для настройки DI для моего проекта Service Fabric.
//This is what I've got so far, and it works great
ServiceRuntime.RegisterServiceAsync(
"MyServiceType",
context => new MyService(context, new MyMonitor()
).GetAwaiter().GetResult();
//This is how I use it
public MyService(StatefulServiceContext context, IMonitor myMonitor)
: base(context)
{
this._myMonitor = myMonitor;
}
Как бы я настроить DI, если MyMonitor
класс зависит от ConfigProvider
класс, как это:
public MyMonitor(IConfigProvider configProvider)
{
this._configProvider = configProvider;
}
2 ответа
Я думаю, что этот вопрос даст вам некоторый свет: почему ServiceRuntime.RegisterServiceAsync возвращает до завершения функции serviceFactory?
Технически, ServiceRuntime.RegisterServiceAsync()
это регистрация зависимостей, она требует, чтобы вы передали serviceTypeName и фабричный метод, отвечающий за создание сервисов Func<StatelessServiceContext, StatelessService> serviceFactory
Фабричный метод получает контекст и возвращает сервис (с сохранением состояния или без сохранения состояния).
Для DI вы должны заранее зарегистрировать все зависимости и вызвать службы разрешения для создания конструктора, например:
var provider = new ServiceCollection()
.AddLogging()
.AddSingleton<IFooService, FooService>()
.AddSingleton<IMonitor, MyMonitor>()
.BuildServiceProvider();
ServiceRuntime.RegisterServiceAsync("MyServiceType",
context => new MyService(context, provider.GetService<IMonitor>());
}).GetAwaiter().GetResult();
PS:
- Никогда не регистрируйте контекст (StatelessServiceContext\StatefulServiceContext) в DI, в подходе с общим процессом несколько разделов могут быть размещены в одном процессе и будут иметь несколько контекстов.
- Этот фрагмент кода не тестировался, я использовал в прошлом, не имею доступа к проверке, если совпадает с тем же кодом, но очень близок к используемому подходу, возможно, потребуются некоторые изменения.
Привет @OscarCabreraRodríguez
Я работаю над проектом, который упрощает разработку надежных сервисов Service Fabric и имеет отличную встроенную поддержку сценариев внедрения зависимостей.
Вы можете найти страницу общей информации о проекте, вики и конкретную информацию о внедрении зависимостей здесь.
Идея в том, что проект отвлекает вас от работы с Service
экземпляр, вместо этого предоставляя вам набор более конкретных объектов.
Вот простой пример приложения ASP.NET Core:
public static void Main(string[] args)
{
new HostBuilder()
.DefineStatefulService(
serviceBuilder =>
{
serviceBuilder
.UseServiceType("ServiceType")
.DefineAspNetCoreListener(
listenerBuilder =>
{
listenerBuilder
.UseEndpoint("ServiceEndpoint")
.UseUniqueServiceUrlIntegration()
.ConfigureWebHost(
webHostBuilder =>
{
webHostBuilder
.ConfigureServices(
services =>
{
// You can configure as usual.
services.AddTransient<IMyService, MyService>();
})
.UseStartup<Startup>();
});
});
})
.Build()
.Run();
[Route("api")]
public class ApiController : Controller
{
public ApiController(IMyService service) { }
[HttpGet]
[Route("value")]
public string GetValue()
{
return $"Value from {nameof(ApiController)}";
}
}
Надеюсь, я правильно понимаю ваш вариант использования и эта информация актуальна.