在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) dependency-injection castle-windsor self-hosting asp.net-web-api
目前我有一个ActionFilter,它从HttpContext获取当前用户名,并将其传递给在服务方法上使用它的操作.例如:
Service.DoSomething(userName);
Run Code Online (Sandbox Code Playgroud)
我现在有理由不在动作级别而是在控制器构造级别执行此操作.目前我正在使用结构图来创建控制器并注入服务.我正在寻找类似的东西:
public interface IUserProvider
{
string UserName { get; }
}
public class HttpContextUserProvider : IUserProvider
{
private HttpContext context;
public HttpContextUserProvider(HttpContext context)
{
this.context = context;
}
public string UserName
{
get
{
return context.User.Identity.Name;
}
}
}
Run Code Online (Sandbox Code Playgroud)
也就是说,我的IoC foo非常弱,因为这是我用过的第一个项目.
所以我的问题是......如何告诉结构图在HttpContextUserProvider的构造函数中传递HttpContext?这看起来很奇怪......我不知道怎么想HttpContext.