有状态服务的依赖注入
Dependency injection for stateful services
我有一个 Service Fabric 有状态服务,其中包含一个 RunAsync 循环和一个 OWIN Web API 侦听器。是否可以将依赖注入添加到 StatefulService 继承的 class 和 API 控制器中?我真的只能得到一个或另一个。
如果我将容器逻辑放在 Startup.cs 中,那么我可以轻松地为 Web API 控制器获取 DI,但不是有状态服务。
如果我将容器逻辑放在 Program.cs 中,那么我可以为有状态服务而不是 Web api 获取它。 (实际上这感觉更像是服务定位器,但在这种情况下我同意)
Program.cs
private static void Main()
{
var builder = new ContainerBuilder();
builder.RegisterModule<MyModule>();
var container = builder.Build();
ILogger logger = container.Resolve<ILogger>();
ServiceRuntime.RegisterServiceAsync("MyService", (context) => new MyService(context, logger)).GetAwaiter().GetResult();
}
如果不将 IContainer 传递给 StatefulService 构造函数,我不知道如何将其用于 Web 的启动初始化 API 以设置 DependencyResolver。
我有一个解决方案,我在通信侦听器创建中创建容器。
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new[] {
new ServiceInstanceListener(CreateOwinCommunicationListener, "owin")
};
}
private ICommunicationListener CreateOwinCommunicationListener(StatelessServiceContext context)
{
var container = CreateContainer();
return new OwinCommunicationListener("api", new Startup(container), context, Log, "WebServiceEndpoint");
}
如果我想访问服务中的容器,我也可以这样做。
我有一个 Service Fabric 有状态服务,其中包含一个 RunAsync 循环和一个 OWIN Web API 侦听器。是否可以将依赖注入添加到 StatefulService 继承的 class 和 API 控制器中?我真的只能得到一个或另一个。
如果我将容器逻辑放在 Startup.cs 中,那么我可以轻松地为 Web API 控制器获取 DI,但不是有状态服务。
如果我将容器逻辑放在 Program.cs 中,那么我可以为有状态服务而不是 Web api 获取它。 (实际上这感觉更像是服务定位器,但在这种情况下我同意)
Program.cs
private static void Main()
{
var builder = new ContainerBuilder();
builder.RegisterModule<MyModule>();
var container = builder.Build();
ILogger logger = container.Resolve<ILogger>();
ServiceRuntime.RegisterServiceAsync("MyService", (context) => new MyService(context, logger)).GetAwaiter().GetResult();
}
如果不将 IContainer 传递给 StatefulService 构造函数,我不知道如何将其用于 Web 的启动初始化 API 以设置 DependencyResolver。
我有一个解决方案,我在通信侦听器创建中创建容器。
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new[] {
new ServiceInstanceListener(CreateOwinCommunicationListener, "owin")
};
}
private ICommunicationListener CreateOwinCommunicationListener(StatelessServiceContext context)
{
var container = CreateContainer();
return new OwinCommunicationListener("api", new Startup(container), context, Log, "WebServiceEndpoint");
}
如果我想访问服务中的容器,我也可以这样做。