Mar*_*ann 27 dependency-injection castle-windsor self-hosting asp.net-web-api
在ASP.NET Web API中,HttpControllerContext实例提供了有关当前环境的大量信息,包括当前请求的URI.
如果服务依赖于此类信息(例如请求URI),则应该可以将该信息注入服务中.
使用Poor Man的DI很容易做到:只需实现一个自定义的IHttpControllerActivator.
然而,随着温莎城堡,这突然变得非常困难.以前,我已经描述了解决这个问题的一种非常复杂的方法,但它取决于PerWebRequest的生活方式,并且事实证明这种生活方式在自托管方案中不起作用,因为HttpContext.Current是空的.
到目前为止,我已经能够通过从自定义IHttpControllerActivator将所需信息作为内联参数传递给Resolve方法来完成这项工作:
public IHttpController Create(
HttpControllerContext controllerContext,
Type controllerType)
{
var baseUri = new Uri(
controllerContext
.Request
.RequestUri
.GetLeftPart(UriPartial.Authority));
return (IHttpController)this.container.Resolve(
controllerType,
new { baseUri = baseUri });
}
Run Code Online (Sandbox Code Playgroud)
但是,默认情况下,仅当立即请求的类型依赖于参数时才会起作用(即,如果请求的Controller本身依赖于该参数baseUri).如果依赖关系baseUri更深层地隐藏在依赖关系层次结构中,则默认情况下它不起作用,因为内联参数不会传播到更深层.
可以使用自定义IDependencyResolver(Castle Windsor IDependencyResolver,而不是ASP.NET Web API IDependencyResolver)更改此行为:
public class InlineDependenciesPropagatingDependencyResolver :
DefaultDependencyResolver
{
protected override CreationContext RebuildContextForParameter(
CreationContext current, Type parameterType)
{
if (parameterType.ContainsGenericParameters)
{
return current;
}
return new CreationContext(parameterType, current, true);
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,true它是作为propagateInlineDependencies构造函数参数传递而不是false默认实现.
为了使用InlineDependenciesPropagatingDependencyResolver类连接容器实例,必须以这种方式构造它:
this.container =
new WindsorContainer(
new DefaultKernel(
new InlineDependenciesPropagatingDependencyResolver(),
new DefaultProxyFactory()),
new DefaultComponentInstaller());
Run Code Online (Sandbox Code Playgroud)
我想知道这是否是这个问题的最佳解决方案,或者是否有更好/更简单的方法?
为了完整起见,我在 Twitter 上从 Krzysztof Ko\xc5\xbamic(温莎城堡的当前维护者)那里得到的答案表明,问题中概述的方法确实是实现这一特定目标的正确方法。
\n\n(但是,我无法链接到该推文,因为克日什托夫的推特帐户受到保护(推文不公开可见。))
\n| 归档时间: |
|
| 查看次数: |
2155 次 |
| 最近记录: |