【ASP.net MVC + DI】ASP.net MVC 使用 DI Framework - Autofac

【ASP.net MVC + DI】ASP.net MVC 使用 DI Framework - Autofac
在一開始我也搞不懂什麼是DI,IoC又是什麼,而且兩個通常都會同時提起,他們有什麼不尋常的關係...直到看了幾位前輩的Blog後才逐漸明朗
好的接下來得開始在專案上時做DI了!在幾位前輩的部落格中,找到幾套好用的DI Framework:Unity及Autofac,這邊選擇以Autofac主要原因是饅頭在網路上找到的資源較為豐富,出錯了還有地方可以詢問與查資料!
OK,選擇好了一個Framework後就開始我們DI的新旅程了!
一開始我們透過nuget來找到Autofac

在一開始我也搞不懂什麼是DI,IoC又是什麼,而且兩個通常都會同時提起,他們有什麼不尋常的關係...直到看了幾位前輩的Blog後才逐漸明朗

 

IoC:Inversion of control,控制反轉,由Martin Fowler提出

系統架構設計應該以抽象的邏輯概念為主,才能更貼近現實世界,才能更符合domain model,當Business logic不變時,需求變更、技術變更、DB變更,都應該要把風險和成本壓到最低。In 91 - [Software Architecture]IoC and DI

DI:Dependency injection,相依住入,透過IoC的概念,讓系統的Method都相依於Interface(介面),在應用程式啟動時去注入Interface所相對應的實體,取代原本以new Class()來產生。

 


好的接下來得開始在專案上時做DI了!在幾位前輩的部落格中,找到幾套好用的DI Framework:Unity及Autofac,這邊選擇以Autofac主要原因是饅頭在網路上找到的資源較為豐富,出錯了還有地方可以詢問與查資料!

OK,選擇好了一個Framework後就開始我們DI的新旅程了!

一開始我們透過nuget來找到Autofac

autofac

因饅頭的專案是MVC 4的專案搭配Web API,所以額外新增這兩個nuget package:Autofac ASP.NET MVC 4 Integration、Autofac ASP.NET Web API Integration

如果是MVC 5 則需安裝:Autofac ASP.NET MVC 5 Integration、Autofac ASP.NET Web API 2 Integration

autofac mvc 4

將這三套DI Framewrok 加入到專案後,就得開始修改程式碼了!

饅頭這邊有使用Repository以及UnitOfWork的設計樣式,所以在一開始需要做一點小小的設定(如未使用可略過此步驟),程式碼的部分是由Kevin前輩所提供的程式碼來實作

程式碼的部分請參考本篇 mrkt 的程式學習筆記 - ASP.NET MVC 使用 Autofac 中的建立 IDbContextFactory 與 DbContextFactory

在Controller移除相依性

原本我們在Controller中會建立一個相對應的Services實體


public class HomeController : Controller
{
    HomeServices services = new HomeServices();
    // 以下省略
}

而我們希望在Controller中移除實體的相依性,然後讓Autofac幫我們自動產生相對應的實體,所以我們要先將Services先抽出一個介面,這邊可以利用Visual Studio中提供的工具來完成

Rebuild Interface

抽出Interface後,我們將Controller中的程式碼修改為


public class HomeController : Controller
{
    private IHomeServices service;

    public HomeController(IHomeServices service)
    {
        this.service = service;
    }
}

讓Autofac為我們注入IHomeServices的實體物件,讓Controller中的Services不會直接產生實體,解除了相依的關係

 

註冊Autofac

我們先在App_Start目錄下新增一個名為AutofacConfig.cs的檔案,並新增以下程式碼


using System.Configuration;
using System.Reflection;
using System.Web.Http;
using System.Web.Mvc;
using Autofac;
using Autofac.Integration.Mvc;
using Autofac.Integration.WebApi;
using Web.CatchNet.Models.DbContextFactory;
using Web.CatchNet.Repository;
using Web.CatchNet.Repository.Interface;

/// <summary>
/// DI設定檔
/// </summary>
public class AutofacConfig
{
    /// <summary>
    /// 註冊DI注入物件資料
    /// </summary>
    public static void Register()
    {
        // 容器建立者
        ContainerBuilder builder = new ContainerBuilder();

        // 註冊Controllers
        builder.RegisterControllers(Assembly.GetExecutingAssembly());
        builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

        // 註冊DbContextFactory
        string connectionString =
            ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
        builder.RegisterType<DbContextFactory>()
            .WithParameter("connectionString", connectionString)
            .As<IDbContextFactory>()
            .InstancePerHttpRequest();

        // 註冊 Repository UnitOfWork
        builder.RegisterGeneric(typeof(GenericRepository<>)).As(typeof(IRepository<>));
        builder.RegisterType(typeof(UnitOfWork)).As(typeof(IUnitOfWork));

        // 註冊Services
        builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
               .Where(t => t.Name.EndsWith("Services"))
               .AsImplementedInterfaces();

        // 建立容器
        IContainer container = builder.Build();

        // 解析容器內的型別
        AutofacWebApiDependencyResolver resolverApi = new AutofacWebApiDependencyResolver(container);
        AutofacDependencyResolver resolver = new AutofacDependencyResolver(container);

        // 建立相依解析器
        GlobalConfiguration.Configuration.DependencyResolver = resolverApi;
        DependencyResolver.SetResolver(resolver);
    }
}

在新增程式碼後,要到Global.asax中註冊


protected void Application_Start()
{
    // 略
    AutofacConfig.Register();
}

如此一來,Autofac在我們系統執行時,會為我們注入相對應的實體!

減少了系統直接依賴實體的問題,也可以在需求變更後快速修改線上服務,甚至替換整個Services

 


參考資料

KKBruce - 使用AUTOFAC和UNITY學習MVC 4,5和WEB API 1,2的IOC,DI技巧

黑暗執行緒 - Autofac筆記 1

mrkt 的程式學習筆記 - ASP.NET MVC 使用 Autofac

愛流浪的小風 - 使用Asp.Net MVC打造Web Api (4) - 套用DI Framework – - Autofac

In 91 - [Software Architecture]IoC and DI

 


 

大家好我是饅頭,希望大家喜歡我的文章

如果有錯誤的地方請不吝指教 ^_^