Как использовать встроенное в.NET Core внедрение зависимостей с Service Fabric

Добрый день,

Недавно я начал экспериментировать с Service Fabric и.NET Core. Я создал Webless API без сохранения состояния и выполнил некоторое DI, используя:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    var connString = Configuration.GetConnectionString("DefaultConnection");
    services.AddScoped<FaxLogic>();
    services.AddDbContext<ApplicationContext>(options => options.UseSqlServer(connString));
}

С учетом вышеизложенного я могу использовать конструктор inject для своего класса FaxLogic, а также для своего класса DbContext (через FaxLogic):

private readonly FaxLogic _faxLogic;
public FaxController(
    FaxLogic faxLogic)
{
    _faxLogic = faxLogic;
}
private readonly ApplicationContext _context;
public FaxLogic(ApplicationContext context)
{
    _context = context;
}

Затем я создал службу без сохранения состояния API без Web. Я хочу иметь доступ к моим FaxLogic и DbContext, как в моем WebAPI, но в методе RunAsync службы без сохранения состояния:

protected override async Task RunAsync(CancellationToken cancellationToken)
{
    // TODO: Replace the following sample code with your own logic 
    //       or remove this RunAsync override if it's not needed in your service.

    while (true)
    {
        cancellationToken.ThrowIfCancellationRequested();

        ServiceEventSource.Current.ServiceMessage(this.Context, "Hello!");

        // do db stuff here!

        await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken);
    }
}

Мне интересно, как бы я это сделал. Я попытался поиграть с методом CreateServiceInstanceListeners() и файлом Program.cs, где используется ServiceRuntime, чтобы зарегистрироваться, но я не могу понять это! Любая помощь будет оценена.

2 ответа

Решение

Решение уже было дано здесь: настройка внедрения зависимостей в Service Fabric с использованием стандартного контейнера ASP.NET Core DI

Таким образом, вы должны зарегистрировать зависимости, прежде чем создавать новый экземпляр службы без сохранения состояния, а затем создать фабричный метод для разрешения зависимостей:

то есть:

public static class Program
{
    public static void Main(string[] args)
    {
        var provider = new ServiceCollection()
                    .AddLogging()
                    .AddSingleton<IFooService, FooService>()
                    .AddSingleton<IMonitor, MyMonitor>()
                    .BuildServiceProvider();

        ServiceRuntime.RegisterServiceAsync("MyServiceType",
            context => new MyService(context, provider.GetService<IMonitor>());
        }).GetAwaiter().GetResult();

Смотрите связанный ответ для более подробной информации.

Taeseo,

Я думаю, что то, что вы ищете, реализовано в проекте, над которым я работаю - CoherentSolutions.Extensions.Hosting.ServiceFabric.

В терминах CoherentSolutions.Extensions.Hosting.ServiceFabric то, что вы ищете, будет выглядеть так:

private static void Main(string[] args)
{
  new HostBuilder()
    .DefineStatelessService(
      serviceBuilder => {
        serviceBuilder
          .UseServiceType("ServiceName")
          .DefineDelegate(
            delegateBuilder => {
              delegateBuilder.ConfigureDependencies(
                dependencies => {
                  dependencies.AddScoped<FaxLogic>();
                });
              delegateBuilder.UseDelegate(
                async (StatelessServiceContext context, FaxLogic faxLogic) => {
                  while (true) {
                    cancellationToken.ThrowIfCancellationRequested();

                    ServiceEventSource.Current.ServiceMessage(context, "Hello!");

                    await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken);
                });
            })
       })
    .Build()
    .Run();
}

Если у вас есть дополнительные вопросы, не стесняйтесь задавать их или проверить вики проекта

Надеюсь, поможет.

Другие вопросы по тегам