The ServiceContext
of a reliable service in Service Fabric is registered with the runtime (DI container) in the program.cs of the service:
ServiceRuntime.RegisterServiceAsync("RelDictQuerySvcType",
context => new RelDictQuerySvc(context)).GetAwaiter().GetResult();
How can I get that ServiceContext back from the DI container? There is no property on the ServiceRuntime to get it back. Also, I did not find it via the FabricClient
. Do I need to put the context on an own static class in the service constructor to be able to get a reference to it somewhere else in my code?
Service Fabric does not really has a build-in DI mechanism, at least it is a very simple one.
If you want to inject dependencies into you services itself you can use a factory. for example:
ServiceRuntime.RegisterServiceAsync("MyStatelessType",
context =>
{
var loggerFactory = new LoggerFactoryBuilder(context).CreateLoggerFactory(applicationInsightsKey);
ILogger logger = loggerFactory.CreateLogger<MyStateless>();
return new MyStateless(context, logger);
}).GetAwaiter().GetResult();
this is a way to inject concrete implementations in your service. This mechanism is used to inject the context as well. Unfortunately, since it is not a full fledged DI container you cannot get this context outside the service instance itself.
So, you have to bring your own DI container to really use it, for example in a stateless web api you can do something like:
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new[]
{
new ServiceInstanceListener(serviceContext =>
new WebListenerCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
{
logger.LogStatelessServiceStartedListening<WebApi>(url);
return new WebHostBuilder().UseWebListener()
.ConfigureServices(
services => services
.AddSingleton(serviceContext)
.AddSingleton(logger)
.AddTransient<IServiceRemoting, ServiceRemoting>())
.UseContentRoot(Directory.GetCurrentDirectory())
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseStartup<Startup>()
.UseUrls(url)
.Build();
}))
};
}
Otherwise you have to do it yourself. There are some initiatives already, see this one for an AutoFac extensions and there is also a Unity extensions.