[.NET] ASP.NET MVC 使用 Autofac 實作 DI Framework
DI 就不多做介紹了,主要目的就是減少程式碼相依性、提高可維護性,還有助於單元測試與平行開發
以前實作都是自己手刻,直到最近才開始接觸 Autofac 這套 IoC Container,
Autofac 使用上有很多優點、很好上手,搭配 ASP.NET MVC 架構使用建構子注入更是方便
可以幫你完成類別註冊、自動注入的動作。而官網和網路上的資料以及討論很多,也不用怕找不到資源。
整理一下實作步驟,使用的專案是 Asp.net Mvc 搭配 Entity Framework
1. 在專案中加入 Autofac
透過 Nuget 安裝 Autofac、Autofac.Mvc,如果有搭配 WebApi,要在額外安裝 Autofac.WebApi
2. 使用 Interface 抽出程式碼邏輯
這邊的東西和 Autofac 比較沒有關係,而是和 DI 有關。
要使用相依性注入,我們應該針對介面寫程式,而不是實踐類別。
假設我們有個 OrderService 負責訂單的處理邏輯,將 OrderService 中的方法抽出成一個介面 IOrderService
public interface IOrderService
{
Order GetOrderById(int id);
void DeleteOrder(int id);
void DeleteOrder(Order order);
void InsertOrder(Order order);
void UpdateOrder(Order order);
//以下略
}
於 OrderService 實作 IOrderService
public class OrderService : IOrderService
{
public Order GetOrderById(int id)
{
using (var context = new DemoContext())
{
return context.Order.Find(id);
}
}
//以下略
}
context 物件應該要寫成 Repository,並宣告成類別層級的私有變數,由建構子初始化後,再給各個 Method 使用,
這樣可以讓程式碼更靈活,但為求範例的簡潔,就先這樣子寫不要弄得太複雜
3. 註冊 Autofac
Service 寫好後,就可以使用 Autofac 來進行註冊,可以撰寫一類別 DependencyRegistrar,
將註冊內容,都寫在 Register 這個靜態 Method 中
public class DependencyRegistrar
{
public static void Register()
{
var builder = new ContainerBuilder();
builder.RegisterType<OrderService>().As<IOrderService>().InstancePerLifetimeScope();
}
}
如果 Service 很多,可以用以下方式處理,指定載入某個組件,並使用 Autofac 提供的方法來完成註冊。
避免漏掉而造成出現錯誤和減少需要反覆手動刪減的時間
var services = Assembly.Load("namespace")
builder.RegisterAssemblyTypes(services).AsImplementedInterfaces();
寫好後在 Global.asax 的 Application_start 方法呼叫 ,讓程式初始時就完成註冊動作,
protected void Application_Start()
{
//略
DependencyRegistrar.Register();
}
4. Enjoy!
最後就可以在 Controller 中使用剛剛寫好的 Serivce 了,我們可以使用建構子注入的方式來完成
在 OrderController 的類別中,建立一類別層級私有變數 _orderService,型別是介面 IOrderService,
並在建構子中傳入介面型別,指派值給 _orderService ,當執行時 Autofac 就會自動建立該 instance 並注入。
public class OrderController : Controller
{
private readonly IOrderService _orderService;
public OrderController(IOrderService orderService)
{
_orderService = orderService;
}
public ActionResult Index(int? id = null)
{
if (id != null)
{
var orderModel = _orderService.GetOrderById(id).ToModel();
return View(orderModel);
}
return View();
}
}
以上介紹的只是基本的使用,Autofac 還有很多的進階應用與操作可以玩玩看。