使用 Castle Windsor 解析 HttpControllerContext [英] Resolving HttpControllerContext with Castle Windsor

查看:28
本文介绍了使用 Castle Windsor 解析 HttpControllerContext的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In the ASP.NET Web API, HttpControllerContext instances provide a lot of information about the current environment, including the URI of the current request.

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

If a service relies on such information (e.g. the request URI), it should be possible to inject that information into the service.

使用Poor Man DI 很容易做到这一点:只需实现自定义IHttpControllerActivator.

This is pretty easy to do using Poor Man's DI: just implement a custom IHttpControllerActivator.

然而,对于温莎城堡,这突然变得非常困难.以前,我已经描述了一个非常复杂的方法来解决这个问题,但它取决于 PerWebRequest 的生活方式,事实证明这种生活方式在自托管场景中不起作用,因为 HttpContext.Current 是空的.

However, with Castle Windsor this suddenly becomes very difficult. Previously, I've described a very convoluted way to resolve this issue, but it hinges on the PerWebRequest lifestyle, and it turns out that this lifestyle doesn't work in self-hosting scenarios, because HttpContext.Current is empty.

到目前为止,我已经能够通过将所需信息作为内联参数从自定义 IHttpControllerActivator 传递给 Resolve 方法来完成这项工作:

So far, I've been able to make this work by passing the desired information as an inline argument to the Resolve method from a custom IHttpControllerActivator:

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 });
}

然而,默认情况下,这仅在立即请求的类型依赖于参数时才有效(即,如果请求的控制器本身依赖于 baseUri).如果对 baseUri 的依赖深埋在依赖层次结构中,默认情况下它不起作用,因为内联参数不会传播到更深层.

However, by default, this only works if the immediately requested type relies on the argument (i.e. if the requested Controller itself depends on the baseUri). If the dependency on baseUri is buried deeper in the dependency hierarchy, it doesn't work by default, because inline arguments aren't propagated to deeper layers.

可以使用自定义 IDependencyResolver(Castle Windsor IDependencyResolver,而不是 ASP.NET Web API IDependencyResolver)更改此行为:

This behavior can be changed with a custom IDependencyResolver (a Castle Windsor IDependencyResolver, not an 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.

Notice that true is being passed as the propagateInlineDependencies constructor argument instead of false, which is the default implementation.

为了将容器实例与 InlineDependenciesPropagatingDependencyResolver 类连接起来,它必须以这种方式构造:

In order to wire up a container instance with the InlineDependenciesPropagatingDependencyResolver class, it must be constructed in this way:

this.container = 
    new WindsorContainer(
        new DefaultKernel(
            new InlineDependenciesPropagatingDependencyResolver(),
            new DefaultProxyFactory()),
        new DefaultComponentInstaller());

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

I'm wondering if this is the best solution to this problem, or if there's a better/simpler way?

推荐答案

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

Just for the sake of completeness, an answer I got from Krzysztof Koźmic (the current maintainer of Castle Windsor) on Twitter indicated that the method outlined in the question is, indeed, the correct way of achieving this particular goal.

(但是,我无法链接到那条推文,因为 Krzysztof 的推特帐户受到保护(推文不公开.))

(However, I can't link to that tweet, since Krzysztof's twitter account is protected (tweets are not publicly visible.))

这篇关于使用 Castle Windsor 解析 HttpControllerContext的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆