Set up Dependency Injection on Service Fabric using default ASP.NET Core DI container

喜你入骨 提交于 2019-11-28 13:02:42

I think this question will give you some light: Why does ServiceRuntime.RegisterServiceAsync return before the serviceFactory func completes?

Technically, the ServiceRuntime.RegisterServiceAsync() is a dependency registration, it requires you to pass the serviceTypeName and the factory method responsible for creating the services Func<StatelessServiceContext, StatelessService> serviceFactory

The factory method receives the context and returns a service (Stateful or stateless).

For DI, you should register all dependencies in advance and call resolve services to create the constructor, something like:

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:

  • Never Register the context (StatelessServiceContext\StatefulServiceContext) in the DI, in a shared process approach, multiple partitions might be hosted on same process and will ahve multiple contexts.
  • This code snippet is not tested, I've used in the past, don't have access to validate if matches the same code, but is very close to the approach used, might need some tweaks.

Hi @OscarCabreraRodríguez

I am working on the project that simplifies development of Service Fabric Reliable Services and it has great built-in support for dependency injection scenarios.

You can find general information project page, wiki and specific information about dependency injection here.

The idea is that project abstracts you from working with Service instance directly instead providing you with a set of more concrete objects.

Here is a simple example for ASP.NET Core application:

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)}";
  }
}

Hope I understand your use case correctly and this information is relevant.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!