Skip to main content
 首页 » 编程设计

dependency-injection之使用 CaSTLe Windsor 解析 HttpControllerContext

2024年10月25日16开发

ASP.NET Web API , HttpControllerContext 实例提供了很多关于当前环境的信息,包括当前请求的 URI。

如果服务依赖于此类信息(例如请求 URI),则应该可以将该信息注入(inject)到服务中。

使用Poor Man's DI 很容易做到这一点:只需implement a custom IHttpControllerActivator .

然而,有了温莎城堡,这突然变得非常困难。以前,I've described a very convoluted way解决这个问题,但它取决于 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 }); 
} 

但是,默认情况下,这仅在立即请求的类型依赖于参数时才有效(即,如果请求的 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); 
    } 
} 

请注意 true作为 propagateInlineDependencies 传递构造函数参数而不是 false ,这是默认实现。

为了将容器实例与 InlineDependenciesPropagatingDependencyResolver 类连接起来,它必须以这种方式构造:
this.container =  
    new WindsorContainer( 
        new DefaultKernel( 
            new InlineDependenciesPropagatingDependencyResolver(), 
            new DefaultProxyFactory()), 
        new DefaultComponentInstaller()); 

我想知道这是否是解决此问题的最佳方法,或者是否有更好/更简单的方法?

请您参考如下方法:

为了完整起见,我在 Twitter 上从 Krzysztof Koźmic(CaSTLe Windsor 的当前维护者)那里得到的回答表明,问题中概述的方法确实是实现这一特定目标的正确方法。

(但是,我无法链接到该推文,因为 Krzysztof 的推特帐户受到保护(推文不公开可见。))