Настройка внедрения зависимостей в Service Fabric с использованием стандартного контейнера ASP.NET Core DI - PullRequest
0 голосов
/ 14 января 2019

Я хотел бы использовать контейнер 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 ]

0 голосов
/ 15 января 2019

Привет @ OscarCabreraRodríguez

Я работаю над проектом, который упрощает разработку надежных сервисов Service Fabric и имеет отличную встроенную поддержку сценариев внедрения зависимостей.

Вы можете найти общую информацию страницу проекта , wiki и конкретную информацию о внедрении зависимостей здесь .

Идея состоит в том, что проект абстрагирует вас от работы с экземпляром 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)}";
  }
}

Надеюсь, я правильно понимаю ваш вариант использования, и эта информация актуальна.

0 голосов
/ 15 января 2019

Я думаю, что этот вопрос даст вам некоторое представление: Почему 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, при подходе с общим процессом несколько разделов могут быть размещены в одном процессе и будут иметь несколько контекстов.
  • Этот фрагмент кода не проверен , я использовал в прошлом, не имею доступа к проверке, если совпадает с тем же кодом, но очень близок к используемому подходу, может потребоваться некоторые настройки .
...