2017-10-16 49 views
0

在服务织物可靠服务的ServiceContext与在服务的Program.cs中运行时(DI容器)注册地:如何获取服务结构中可靠服务的ServiceContext?

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

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

+0

你想在哪里访问它? –

+0

服务实现类以外的任何位置。在我的具体情况中,在由NServiceBus实例化的事件处理程序类中,所以我不能只将上下文传递给它。 –

回答

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扩展。