1. 程式人生 > >搞定.NET MVC IOC控制反轉,依賴注入

搞定.NET MVC IOC控制反轉,依賴注入

一直聽說IOC,但是一直沒接觸過,只看例子好像很高達上的樣子,今天抽了點時間實現了下,當然也是藉助部落格園裡面很多前輩的文章來搞的!現在做個筆記,防止自己以後忘記!

1、首先建立MVC專案

2、然後新建一個介面IServiceA

public interface IServiceA
    {
        string Name();
    }

實現介面

public class ServiceA : IServiceA
    {
        public string Name()
        {
            return "Service A";
        }
    }

簡單點說,就是要把IService的呼叫自動注入ServiceA型別

新建MVC控制器:HomeController並新增建構函式

    public class HomeController : Controller
    {
        protected Service.IServiceA ServiceA;
        public HomeController(Service.IServiceA a)
        {
            this.ServiceA = a;
        }
    }

下面我們來實現如何通過IOC把IServiceA注入為ServiceA型別

Nuget新增引用,搜尋Unity,如果提示失敗的話,就用Nuget的命令新增以前的版本,不知道怎麼敲就直接新增PolicyInJection引用好了

新建類:UnityDependencyReslover

public class UnityDependencyReslover : System.Web.Mvc.IDependencyResolver
{
IUnityContainer container;
public UnityDependencyReslover(IUnityContainer container)
{
this.container = container;
}

public object GetService(Type t)
{
if (t == null) return null;
if (!container.IsRegistered(t)) return null;
return container.Resolve(t);
}

public IEnumerableobject GetServices(Type t)
{
return container.ResolveAll(t);
}
}

這個沒有啥好說的把,就是實現型別對映的解析而已

Global.asax的Application_Start中註冊解析型別對映

IUnityContainer container = new UnityContainer(); 
container.RegisterTypeService.IServiceA, Service.ServiceA(); 
container.RegisterTypeIControllerFactory, IOC.MyControllerFactory(); 
DependencyResolver.SetResolver(new IOC.UnityDependencyReslover(container));

看標紅的那句,這裡簡單說明一下,HomeController的建構函式帶了引數,預設情況下MVC的控制器初始化沒有引數的,這裡我們要自己去實現對引數的解析,也就是在這個地方注入引數,不然你的MVC控制器無法訪問

新建:MyControllerFactory繼承System.Web.Mvc.DefaultControllerFactory
public class MyControllerFactory : DefaultControllerFactory 

IUnityContainer container; 
public MyControllerFactory(IUnityContainer container)

this.container = container; 

protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)

{
if (controllerType == null) return null;
return container.Resolve(controllerType) as IController;
}
}

這樣就行啦!

在你的MVC的HomeController裡面新增一個Action訪問下IServiceA的Name方法試試,是不是可以了!

這裡我要說明一下,有幾個地方要注意:那個IUnityContainer 要統一,先前我嘗試過一直不成功,後來發現是有的地方用的是UnityContainer,所以還是要認真一點!

新增程式碼,程式碼無法高亮加粗,所以沒用程式碼形式新增!