8

我像这样注册了统一容器:

    var container = new UnityContainer();

    container.RegisterType<ICacheManager, CacheManager>(new ContainerControlledLifetimeManager())

是否可以从控制器访问此“容器”

4

4 回答 4

12

不知道你为什么需要它,但这里是代码:

public ActionResult Area51()
    {
        var _service = DependencyResolver.Current.GetService(typeof (IDummyService));

        return View();
    }

如果您尝试做的是注入控制器,您应该设置 DepedencyResolver 以在 Global.asax 的应用程序启动中使用您的 IoC 容器。然后,MVC 会自动向你的控制器注入依赖。

var container = new UnityContainer();
DependencyResolver.SetResolver(new Unity.Mvc4.UnityDependencyResolver(container));

在这里查看更多示例:

http://www.dotnet-tricks.com/Tutorial/dependencyinjection/632V140413-Dependency-Injection-in-ASP.NET-MVC-4-using-Uni​​ty-IoC-Container.html

于 2014-07-26T23:49:36.513 回答
6

我假设您正在使用容器解析一些 Controller 实例。如果是这种情况,您可以让控制器像其他任何东西一样接收 IUnityContainer 作为依赖项。

你想达到什么目的?在已解析的类中获取容器并不是很好,因为它将类与容器耦合在一起,并且通常可以用其他机制替换。

class Program
{
    static void Main(string[] args)
    {
        var container = new UnityContainer();

        var foo = container.Resolve<MyController>();
    }
}

public class MyController
{
    private IUnityContainer container;

    public MyController(IUnityContainer container)
    {
        this.container = container;
    }
}
于 2012-11-05T11:49:54.593 回答
5

为了方便起见,我经常这样做的一种方法是将容器声明为 Global.ascx.cs 文件中的全局变量,例如:

public class MvcApplication : System.Web.HttpApplication
{
    public static UnityContainer Container;

    protected void Application_Start()
    {
         // assuming your initialize here
    } 
}

然而,这是相当hack-ish。

正确的做法是使用 Unity 来解析您的控制器(请参阅这篇关于创建统一控制器工厂的文章),然后允许统一在解析控制器时将任何依赖项注入您的控制器。

所以像这样的控制器:

public MyController: Controller {

 public ICacheManager CacheManager {get;set;}

}

将自动解析您的容器已注册的任何依赖项。

于 2012-11-05T11:57:14.667 回答
4

尽管有可能,但最好避免它。

最好通过构造函数参数获取控制器所需的任何依赖项。这样,类(控制器)就清楚地说明了它运行所需的依赖项。

如果配置正确,容器将提供这些依赖项及其依赖项(如果有的话),依此类推。

IoC 容器的使用通常应仅限于应用程序内的一个位置(称为组合根)。对容器的任何额外引用/调用都容易导致Service Locator 反模式。有关这种方法可能不好的原因,请参阅链接文章。

于 2012-11-05T12:14:05.820 回答