我注册了这样的统一容器:
var container = new UnityContainer();
container.RegisterType<ICacheManager, CacheManager>(new ContainerControlledLifetimeManager())
是否可以从控制器
访问此“容器”答案 0 :(得分:11)
不确定为什么需要它,但这里是代码:
public ActionResult Area51()
{
var _service = DependencyResolver.Current.GetService(typeof (IDummyService));
return View();
}
如果你要做的是注入一个Controller,你应该设置DepedencyResolver在Global.asax的应用程序启动时使用你的IoC容器。然后,MVC将自动为您的控制器注入依赖。
var container = new UnityContainer();
DependencyResolver.SetResolver(new Unity.Mvc4.UnityDependencyResolver(container));
在这里查看更多示例:
答案 1 :(得分: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;
}
}
答案 2 :(得分:5)
为方便起见,我经常这样做的一种方法是将您的容器声明为Global.ascx.cs文件中的全局变量,如:
public class MvcApplication : System.Web.HttpApplication
{
public static UnityContainer Container;
protected void Application_Start()
{
// assuming your initialize here
}
}
然而,这是相当黑客的。
正确的做法是使用Unity来解析控制器(See this article on creating a unity controller factory),然后允许Unity在解析控制器时将任何依赖项注入控制器。
所以控制器如:
public MyController: Controller {
public ICacheManager CacheManager {get;set;}
}
会自动解析您的容器已注册的所有依赖项。
答案 3 :(得分:4)
尽管有可能,但最好避免它。
最好通过构造函数参数获取控制器所需的任何依赖项。这样,类(控制器)就可以清楚地知道它运行所需的依赖项。
如果配置正确,容器将提供这些依赖项及其依赖项(如果有),依此类推。
IoC容器的使用通常应仅限于应用程序内的一个位置(称为组合根)。对容器的任何额外引用/调用都容易导致Service Locator anti-pattern。请参阅链接文章,了解这种方法可能不好的原因。