【发布时间】:2016-02-10 14:50:49
【问题描述】:
我创建了一个使用 SimpleInjector 的 WebApi 应用程序。
现在,API 的用户希望 WCF 端点使用它(无论出于何种原因)。
为了让事情变得更简单,我只想从 WCF 服务内部调用 WebApi 控制器:
public class MyService : IMyService
{
private MyApiController controller;
public MyService(IMyInjection inject)
{
controller = new MyApiController(inject);
}
public int GetResult(string data)
{
return controller.GetResult(data);
}
}
为了使其在 WebApi 中工作,我的控制器当前使用WebApiRequestLifeStyle 生活方式的注入,我尝试“添加”SimpleInjector WCF Integration:
public static void LoadDependencyInjection()
{
var container = new Container();
container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();
container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
// some more registration
// configure WCF to use SimpleInjector
container.RegisterWcfServices(Assembly.GetExecutingAssembly());
// verify
container.Verify();
// configure the global WebApi to use SimpleInjector
GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
// configure WCF to use SimpleInjector
SimpleInjectorServiceHostFactory.SetContainer(container);
}
显然,WCF 服务不喜欢 WebApi 的生活方式,当我尝试调用方法时会抛出错误:
ITransferOrderRequest 注册为“Web API 请求”生活方式,但实例是在 Web API 请求的上下文之外请求的。
更新
我尝试创建第二个具有不同生活方式的容器:
public static void LoadDependencyInjection()
{
// WebApi container
var webApiContainer = CreateContainer(new WebApiRequestLifestyle(true));
webApiContainer.RegisterWebApiControllers(GlobalConfiguration.Configuration);
webApiContainer.EnableHttpRequestMessageTracking(GlobalConfiguration.Configuration);
// WCF container
var wcfContainer = CreateContainer(new WcfOperationLifestyle(true));
wcfContainer.RegisterWcfServices(Assembly.GetExecutingAssembly());
// verify
webApiContainer.Verify();
wcfContainer.Verify();
// configure the global WebApi to use SimpleInjector
GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(webApiContainer);
// configure WCF to use SimpleInjector
SimpleInjectorServiceHostFactory.SetContainer(wcfContainer);
}
private static Container CreateContainer(ScopedLifestyle lifestyle)
{
var container = new Container();
// set the default lifestyle
container.Options.DefaultScopedLifestyle = lifestyle;
// here I register a bunch of interfaces/instances using the Scoped lifestyle
return container;
}
但是第二次调用container.Options.DefaultScopedLifestyle = lifestyle;(使用WcfOperationLifestyle)也改变了第一个容器的默认生活方式!在这种情况下,当我调用我的 WebApi 服务时,我得到了同样的错误,但反过来:
IMyStuff 注册为 WCF 操作生活方式。
我已经看到有一种 Hybrid 生活方式,但是我不知道如何检测它当前是 WCF 还是 WebApi 请求...
谢谢!
【问题讨论】:
-
您是否反对让 WCF 通过 HTTP 发送请求(使用类似
WebClient),而不是尝试新建控制器?我认为您的控制器不会通过您提出的解决方案获得 WebAPI 请求管道的所有好处。 -
为什么不将
ScopedLifestyle实例作为参数传递给LoadDependencyInjection()方法?这样,每个应用程序都可以拥有自己的范围生活方式(这正是该功能的设计目的)。 -
@danludwig :您希望 WCF 服务通过 HTTP 调用 REST 服务吗?老实说,我不太喜欢这种解决方案。
-
@Steven :我尝试创建 2 个容器并更改
DefaultScopedLifestyle但似乎(也许这是一个错误?)覆盖一个容器上的默认值会覆盖另一个容器。 -
据我所知,不存在导致 DefaultScopedLifestyle 实例在容器之间共享的错误。如果您能够通过失败的单元测试来证明这一点,请将其作为问题发布在 Simple Injector 的 Github 项目页面上。
标签: wcf asp.net-web-api simple-injector