c# – ASP Web Api – IoC – 解析HttpRequestMessage
我正试图用ASP.NET WebAPI设置Castle Windsor.
我也使用Hyprlinkr包(https://github.com/ploeh/Hyprlinkr),因此需要一个HttpRequestMessage的实例注入到我的控制器的一个依赖项中. 我正在跟随Mark Seemann – http://blog.ploeh.dk/2012/04/19/WiringHttpControllerContextWithCastleWindsor.aspx的这篇文章,但是我发现尽管API运行,但是当我打电话时,请求就挂起来了.没有错误信息.就好像它处于无限循环.它挂在我的Custom ControllerActivator中的Resolve的调用上 我想我的一些城堡注册错了.如果我删除上述文章中提到的那些,那么我可以成功地调用API(尽管没有需要解决的依赖关系) 有任何想法吗? 代码在下面 //Global.asax public class WebApiApplication : HttpApplication { private readonly IWindsorContainer container; public WebApiApplication() { container = new WindsorContainer( new DefaultKernel( new InlineDependenciesPropagatingDependencyResolver(),new DefaultProxyFactory()),new DefaultComponentInstaller()); container.Install(new DependencyInstaller()); } protected void Application_Start() { GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator),new WindsorCompositionRoot(this.container)); } // installer public class DependencyInstaller : IWindsorInstaller { public void Install(IWindsorContainer container,IConfigurationStore store) { container.AddFacility<TypedFactoryFacility>(); container.Register( Component.For<ValuesController>() .Named("ValuesController") .LifeStyle.PerWebRequest,Component.For<IResourceLinker>() .ImplementedBy<RouteLinker>() .LifeStyle.PerWebRequest,Component.For<IResourceModelBuilder>() .ImplementedBy<ResourceModelBuilder>() .LifeStyle.PerWebRequest,Component.For<HttpRequestMessage>() .Named("HttpRequestMessage") .LifeStyle.PerWebRequest ); } } //Activator public class WindsorCompositionRoot : IHttpControllerActivator { private readonly IWindsorContainer container; public WindsorCompositionRoot(IWindsorContainer container) { this.container = container; } public IHttpController Create( HttpRequestMessage request,HttpControllerDescriptor controllerDescriptor,Type controllerType) { var controller = (IHttpController)this.container.Resolve(controllerType,new { request = request }); request.RegisterForDispose( new Release( () => this.container.Release(controller))); return controller; } // DependencyResolver public class InlineDependenciesPropagatingDependencyResolver : DefaultDependencyResolver { protected override CreationContext RebuildContextForParameter(CreationContext current,Type parameterType) { if (parameterType.ContainsGenericParameters) { return current; } return new CreationContext(parameterType,current,true); } } 编辑*********** 所以我设置了一个场景,控制器只需要一个HttpRequestMessage作为一个ctor参数,并发现: 这样做: //controller public class ValuesController : ApiController { private readonly HttpRequestMessage _httpReq; public ValuesController(HttpRequestMessage httpReq) { _httpReq = httpReq; } //IHttpControllerActivator public IHttpController Create( HttpRequestMessage httpRequest,Type controllerType) { var controller = (IHttpController)this.container.Resolve( controllerType,new { httpReq = httpRequest }); return controller; 但是,这不是. //controller public class ValuesController : ApiController { private readonly HttpRequestMessage _httpReq; public ValuesController(HttpRequestMessage request) { _httpReq = request; } //IHttpControllerActivator public IHttpController Create( HttpRequestMessage request,new { request = request }); return controller; 即当anon对象具有称为“请求”的属性,并且控制器ctor arg被称为“请求”时.它以某种方式使控制器认为它的请求属性为null.这是什么原因导致我看到的错误:
读了这个 它解释了类似的情况. 当然,hyprlinkr具有称为“request”的HttpRequestMessage的ctor参数,因此我需要使用该属性名称指定anon对象. 有任何想法吗? 解决方法
这是一个适用于我的组合根:
public class WindsorCompositionRoot : IHttpControllerActivator { private readonly IWindsorContainer container; public WindsorCompositionRoot(IWindsorContainer container) { this.container = container; } public IHttpController Create( HttpRequestMessage request,Type controllerType) { var controller = (IHttpController)this.container.Resolve( controllerType,new { request = request }); request.RegisterForDispose( new Release( () => this.container.Release(controller))); return controller; } private class Release : IDisposable { private readonly Action release; public Release(Action release) { this.release = release; } public void Dispose() { this.release(); } } } 以下是我创建容器的方式: this.container = new WindsorContainer( new DefaultKernel( new InlineDependenciesPropagatingDependencyResolver(),new DefaultComponentInstaller()) .Install(new MyWindsorInstaller()); 这里是InlineDependenciesPropagatingDependencyResolver: public class InlineDependenciesPropagatingDependencyResolver : DefaultDependencyResolver { protected override CreationContext RebuildContextForParameter( CreationContext current,true); } } 最后,我如何注册RouteLinker: container.Register(Component .For<RouteLinker,IResourceLinker>() .LifestyleTransient()); 需要注意的一点是,ApiController基类有一个名为Request of HttpRequestMessage类型的公共属性.如my book节第10.4.3节所述,Windsor将尝试为每个可写属性分配一个值(如果它具有匹配的组件),并且匹配不区分大小写. 当您将HttpRequestMessage命名请求传递给Resolve方法时,这正是发生的情况,因此您需要告诉Castle Windsor它应该放弃ApiControllers的属性注入.以下是我在公约注册中如何使用: container.Register(Classes .FromThisAssembly() .BasedOn<IHttpController>() .ConfigureFor<ApiController>(c => c.Properties(pi => false)) .LifestyleTransient()); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |