Search code examples
c#.net-coreazure-service-fabric

How to use .NET Core's Built in Dependency Injection with Service Fabric


Good afternoon,

I recently started experimenting with Service Fabric and .NET Core. I created a Stateless Web API and performed some DI using:

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

With the above I can use constructor inject on my FaxLogic class as well as my DbContext class (through the FaxLogic):

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

I then created a non-Web API stateless service. I want to be able to access my FaxLogic and DbContext like in my WebAPI, but within the RunAsync method of the stateless service:

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

I am wondering how I'd do it. I tried playing with the CreateServiceInstanceListeners() method and the Program.cs file where ServiceRuntime is is used to register but I can't seem to figure it out! Any help would be appreciated.


Solution

  • The solution has been already answered here: Set up Dependency Injection on Service Fabric using default ASP.NET Core DI container

    In summary, you have to register the dependencies before you create a new instance of your stateless service and then create a factory method to resolve the dependencies:

    i.e:

    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();
    

    See the linked answer for more details.