.Net Framework使用Autofac實現依賴註入 前言 最近也是找了快2周的工作了,收到的面試邀請也就幾個,然後有個面試題目是用asp.net mvc + Entityframework 做一個學生信息增刪改查系統。因為題目要求了用Entityframework 也就是EF 那也就不上co ...
.Net Framework使用Autofac實現依賴註入
前言
最近也是找了快2周的工作了,收到的面試邀請也就幾個,然後有個面試題目是用asp.net mvc + Entityframework 做一個學生信息增刪改查系統。因為題目要求了用Entityframework 也就是EF 那也就不上core了,web項目也是用Framework 4.8去做的。
本文的重點是IOC容器,在Framework 中是沒有自帶的IOC容器的,那麼就需要使用第三方庫去實現依賴註入,我這裡用的是Autofac。
如果不使用IOC容器去管理類,那麼操作資料庫和使用類方法則是
using(MydbContext db = new MydbContext){
db....
}
StudentService s = new StudentService();
s.Add();
使用方法
Nuget包
首先需要下載2個Nuget包,分別是:
dotnet add package Autofac --version 7.1.0
dotnet add package Autofac.Mvc5 --version 6.1.0
配置文件
然後在配置文件中,也就是Global.asax.cs
文件
然後需要添加如下代碼:
// 創建 Autofac 容器生成器
var builder = new ContainerBuilder();
// 註冊 EF 上下文
builder.RegisterType<SchoolContext>().InstancePerRequest();
// 註冊其他服務
builder.RegisterType<StudentService>().As<IStudentService>().InstancePerRequest();
// 註冊控制器
builder.RegisterControllers(typeof(HomeController).Assembly);
// 構建容器
var container = builder.Build();
// 設置 ASP.NET MVC 的依賴解析器為 Autofac
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
上面我註入了一個SchoolContext資料庫上下文服務,用於操作資料庫
然後註冊了StudentService服務,裡面是增刪改查代碼
舉個例子:
public interface IStudentService{
//刪除
Task<int> DelAsync(int id);
}
public class StudentService:IStudentService
{
private readonly SchoolContext _dbContext;
public StudentService(SchoolContext dbContext)
{
_dbContext = dbContext;
}
public async Task<int> DelAsync(int id)
{
var student = _dbContext.Students.Include("Score").FirstOrDefault(s => s.Id == id);
if (student != null)
{
// 刪除關聯的成績表
if (student.Score != null)
{
_dbContext.Scores.Remove(student.Score);
}
// 刪除學生
_dbContext.Students.Remove(student);
return await _dbContext.SaveChangesAsync();
}
return 0;
}
}
上面StudentService類實現了IStudentService介面的方法,並且註入了SchoolContext依賴進行資料庫操作。
public class HomeController : Controller
{
private readonly IStudentService _studentService;
public HomeController(IStudentService studentService)
{
_studentService = studentService;
}
public async Task<ActionResult> DelStudent(int id)
{
int result = await _studentService.DelAsync(id);
if (result > 0)
{
TempData["SuccessMessage"] = "學生信息刪除成功";
return RedirectToAction("Index");
}
TempData["SuccessMessage"] = "學生信息刪除失敗";
return RedirectToAction("Index");
}
}
上面的控制器則是註入了IStudentService然後就可以調用它的刪除學生信息的方法了。
我們需要註意的是需要把資料庫上下文和服務類交給容器去管理。
// 註冊 EF 上下文
builder.RegisterType<SchoolContext>().InstancePerRequest();
// 註冊其他服務
builder.RegisterType<StudentService>().As<IStudentService>().InstancePerRequest();
// 註冊控制器
builder.RegisterControllers(typeof(HomeController).Assembly);
同時也要註冊控制器,一開始我去寫的的時候沒有註冊控制器,然後會報構造函數不能為空的錯誤!
生命周期
- InstancePerDependency:每次解析時都創建一個新的實例。這是預設的生命周期管理方式。
- SingleInstance:整個應用程式中只創建一個實例,併在後續的解析中重用該實例。
- InstancePerLifetimeScope:每個生命周期範圍內只創建一個實例。生命周期範圍可以通過Autofac的
BeginLifetimeScope()
方法創建。 - InstancePerMatchingLifetimeScope:與
InstancePerLifetimeScope
類似,但只有在解析時與指定的生命周期範圍匹配時才會創建實例。 - InstancePerRequest:在Web應用程式中,每個HTTP請求都創建一個新的實例。這通常用於在Web API或MVC應用程式中註冊服務。
- InstancePerOwned:在每個
Owned<T>
上創建一個新的實例。Owned<T>
是一個特殊的類型,用於在需要時創建和釋放實例。
參考資料
-
控制範圍和生存期 — Autofac 7.0.0 文檔 https://autofac.readthedocs.io/en/latest/lifetime/index.html#example-web-application
-
NuGet 畫廊 |Autofac.Mvc5 6.1.0 https://www.nuget.org/packages/Autofac.Mvc5