我创建了一个使用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运营生活方式。
我已经看到有混合生活方式,但我不知道如何检测它目前是否是WCF或WebApi请求......
谢谢!
答案 0 :(得分:3)
我不知道如何检测它当前是否是WCF或WebApi请求......
您可以通过检查OperationContext.Current != null
。
var lifestyle = Lifestyle.CreateHybrid(
lifestyleSelector: () => OperationContext.Current != null,
trueLifestyle: new WcfOperationLifestyle(true),
falseLifestyle: new WebApiRequestLifestyle()
);
我不知道通过新手控制器而失去的东西"
要在评论中澄清我的建议,我了解你的来源。我仍然认为你应该考虑在完全排除之前通过HTTP做这件事。你可以克服" hardwire路线"将URL作为WCF项目的app.config的一部分。有一些不错的配置转换工具,您可以使用它来为不同的环境生成不同的路由。更改配置以修改程序行为是松散耦合的,并且具有高度凝聚力。
效率稍差,但我认为如果实际额外延迟足够小,成本可能是合理的。您丢失的内容是添加到控制器的所有WebAPI请求管道优势,例如内容协商,过滤器等。由于您没有发布任何代码并且您的决定正常,我认为您确实是只有GetResults(string data)
方法体具有其作用域依赖性,并且不需要任何其他内容。
但请注意,您的决定会在WCF服务和WebAPI控制器之间创建比HTTP网络调用更紧密的耦合。