如何在Service Fabric中获取可靠服务的ServiceContext?

时间:2017-10-16 09:11:37

标签: c# azure-service-fabric

Service Fabric中可靠服务的ServiceContext已在服务的program.cs中注册到运行时(DI容器):

ServiceRuntime.RegisterServiceAsync("RelDictQuerySvcType",
                    context => new RelDictQuerySvc(context)).GetAwaiter().GetResult();

如何从DI容器中恢复ServiceContext? ServiceRuntime上没有任何属性可以将其恢复。另外,我没有通过FabricClient找到它。我是否需要在服务构造函数中将上下文放在自己的静态类上,以便能够在我的代码中的其他位置获取对它的引用?

1 个答案:

答案 0 :(得分:1)

Service Fabric并没有真正的内置DI机制,至少它是一个非常简单的机制。

如果要将依赖项注入服务本身,可以使用工厂。例如:

ServiceRuntime.RegisterServiceAsync("MyStatelessType",
                context =>
                {
                    var loggerFactory = new LoggerFactoryBuilder(context).CreateLoggerFactory(applicationInsightsKey);
                    ILogger logger = loggerFactory.CreateLogger<MyStateless>();

                    return new MyStateless(context, logger);
                }).GetAwaiter().GetResult();

这是一种在服务中注入具体实现的方法。此机制也用于注入上下文。不幸的是,由于它不是一个完整的DI容器,因此无法在服务实例本身之外获得此上下文。

所以,你必须带上你自己的DI容器才能真正使用它,例如在无状态web api中,你可以做类似的事情:

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

否则你必须自己动手。已有一些举措,请参阅this one了解AutoFac扩展程序,还有Unity个扩展程序。