1

在普通的 ASP.MVC 项目中,我们使用 Unity 和来自http://unitymvc3.codeplex.com/的 Unity.Mvc3 包配置依赖解析器

我们已经向HierarchicalLifetimeManager注册了这个测试服务

container.RegisterType<ITestService, TestService>(new HierarchicalLifetimeManager());

我们将容器与 Global.asax.cs 中的 Mvc 连接起来:

System.Web.Mvc.DependencyResolver.SetResolver(new Unity.Mvc3.UnityDependencyResolver(container));

我们运行这个测试控制器:

public class TestController : Controller
{
    private readonly ITestService _service;
    public TestController(ITestService service)
    {
        this._service = service;
    }
    public ActionResult Test()
    {
        var locatedService = System.Web.Mvc.DependencyResolver.Current.GetService<ITestService>();
        if (_service == locatedService)
            return View("Success - Same Service");//This is always the result in an MVC controller
        else
            throw new Exception("Failure - Different Service Located");//This is never the result in an MVC controller
    }
}

然而,在这个项目中,我们添加了一些 WebAPI 控制器。

我们在 global.asax.cs 中有这个配置(现在使用http://unitywebapi.codeplex.com/。但我愿意接受建议):

System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);

我们创建了一个ApiTestController类似于从TestController继承ApiController而不是从Controller。但是,ApiTestController 未通过测试。我知道System.Web.Mvc.DependencyResolver类和属System.Web.Mvc.DependencyResolver.Current​​性是特定于 Mvc 的。但是 WebAPI 有等价物吗?

System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver.GetService不起作用,因为该System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver实例是我配置的父容器。它不是用于将 ITestService 注入构造函数的子控制器。

这个用户似乎有类似的问题:http : //unitywebapi.codeplex.com/discussions/359413 但我觉得这可能更多地与 ASP.NET 的 WebAPI 相关,而不是与 Unity 相关。

谢谢

4

3 回答 3

2

在查看了http://unitymvc3.codeplex.com/http://unitywebapi.codeplex.com/的源代码后,我创建了这个类:

public class MyUnityDependencyResolver : Unity.Mvc3.UnityDependencyResolver, System.Web.Http.Dependencies.IDependencyResolver
{
    public MyUnityDependencyResolver(IUnityContainer container)
        : base(container)
    {
    }

    public System.Web.Http.Dependencies.IDependencyScope BeginScope()
    {
        return this;
    }

    public void Dispose()
    {
        Unity.Mvc3.UnityDependencyResolver.DisposeOfChildContainer();
    }
}

gobal.asax.cs 中的配置:

var myResolver = new MyUnityDependencyResolver(container);
System.Web.Mvc.DependencyResolver.SetResolver(myResolver);
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = myResolver;

Unity.Mvc3.UnityDependencyResolver用于HttpContext.Current.Items管理子容器。 MyUnityDependencyResolver可能不是最“正确”的实现System.Web.Http.Dependencies.IDependencyResolver,但到目前为止它似乎有效。

如果没有其他人有更好的答案,我会在几天内将此标记为答案。

于 2012-10-30T17:54:14.057 回答
1

不幸的是,当您调用 GlobalConfiguration.Configuration.DependencyResolver.GetService 时,它​​会完全忽略任何范围并使用在应用程序生命周期内存在的外部非子容器进行解析。这是 Web Api 的一个问题,并且无法对控制器之外的每个请求的依赖项使用构造函数注入。正如您所说,令人困惑的是,这与 MVC 完全不同。

您可以做的是使用 HttpRequestMessage 的 GetDependencyScope() 扩展方法。将 HierarchicalLifetimeManager 与 Unity.WebApi 结合使用时,您使用此解决的任何问题都将在每个请求范围内。该请求可从操作过滤器和处理程序中获得,因此可能是一种可行的解决方法。

显然,这是纯粹的服务位置而不是依赖注入,这远非理想,但我还没有找到另一种方法来访问控制器之外的每个请求的依赖关系。

有关更多信息,请参阅此帖子

于 2013-04-03T15:49:25.617 回答
0

DependencyResolver不是 ASP.NET WebAPI 中依赖注入的正确接缝。

Mark Seemann 有两篇关于使用 WebAPI 进行 DI 的非常好的文章。

使用 ASP.NET Web API 进行依赖注入和生命周期管理

ASP.NET Web API 中的依赖注入与 Castle Windsor

如果你想做对,你应该看看他们。

于 2012-10-31T08:15:36.940 回答