使用Autofac实现MVC应用中的仓储模式

在软件开发中,数据访问是每个应用程序不可或缺的一部分。为了有效地管理数据访问代码,通常会采用一种称为“仓储模式”的设计模式。这种模式通过在业务逻辑和数据访问层之间添加一个中间层,即仓储层,来隔离数据访问代码。这样做的好处是,当数据库操作需要修改时,只需在一个地方进行更改,而不必在多个控制器方法中重复修改。此外,这种模式还有助于避免代码的重复和提高代码的可维护性。

直接与数据访问层交互的问题

在不使用仓储模式的情况下,控制器方法会直接与Entity Framework等数据访问技术进行交互。这种方法存在几个问题:

  • 代码重复:如果多个控制器需要修改同一个实体,那么相同的代码会在每个控制器方法中重复出现。
  • 未来修改困难:如果数据库操作需要修改,那么所有使用该操作的地方都需要进行修改,这会增加维护的难度。
  • 设计不当:将业务逻辑与数据访问代码混合在一起并不是一个好的设计方法。

使用仓储模式的优势

通过使用仓储模式,控制器方法将与仓储层进行交互,而不是直接与数据访问层交互。这种方法的优势包括:

  • 单一修改点:如果未来需要对数据库操作进行修改,只需在仓储层进行修改即可,因为所有的业务逻辑都会根据需求写在相应的方法中。

环境准备

在开始之前,需要准备以下环境:

  • Visual Studio 2013
  • Northwind数据库:如果没有,请从下载.bak文件并恢复。
  • SQL Server 2012
  • MVC 5
  • Autofac库:通过Nuget在线获取
  • AutofacMVC集成库:通过Nuget在线获取
  • Entity Framework库:用于存储数据

项目结构

将创建两个主要的文件夹:

数据访问层包含三个项目,都是类库类型:

  • Repository_Database:包含Entity Framework。
  • Repository_RepoClasses:包含与数据库交互的仓储类。
  • Repository_RepoInterfaces:包含仓储类的接口。

在创建项目之前,请确保已经恢复了Northwind数据库。

创建数据模型

在Repository_Database项目中,将创建一个数据模型。

// 创建数据模型的步骤 Repository_Database - 右键 -> 添加 -> 新建项 -> 在左侧点击数据 -> 选择ADO.NET实体数据模型 -> 选择从数据库生成() -> 然后选择恢复的Northwind数据库() // 选择是否在连接字符串中包含路径 // 可以选择为整个数据库创建edmx,或者只为需要的表创建edmx,在本例中将使用客户表

接下来,将为Northwind_DBEntities类创建一个接口:

// 创建接口的步骤 右击 -> 选择重构 -> 提取接口 // 覆盖DbContext的Save方法

创建仓储类

在RepositoryPattern_RepoClasses项目中,将添加一个名为CustomerRepository.cs的类,并实现ICustomerRepository接口。

// CustomerRepository类的实现 public class CustomerRepository : ICustomerRepository { INorthwind_DBEntities NorthwindContext; public CustomerRepository(INorthwind_DBEntities db) { NorthwindContext = db; } public IEnumerable<Customer> SelectAll() { return NorthwindContext.Customers.ToList(); } public Customer SelectByID(string id) { return NorthwindContext.Customers.Find(id); } public void Insert(Customer obj) { NorthwindContext.Customers.Add(obj); } public void Delete(string id) { var value = NorthwindContext.Customers.Where(i => i.CustomerID == id).FirstOrDefault(); NorthwindContext.Customers.Remove(value); } public void Save() { NorthwindContext.SaveChanges(); } }

创建接口

在RepositoryPattern_RepoInterfaces项目中,将为之前创建的类创建接口。

// ICustomerRepository接口的实现 public interface ICustomerRepository { IEnumerable<Customer> SelectAll(); Customer SelectByID(string id); void Insert(Customer obj); void Delete(string id); void Save(); }

创建Web项目

在Web文件夹中,将创建一个MVC项目,并添加Autofac和EntityFramework的DLL。

// 创建MVC项目的步骤 右击 -> 选择添加新项目 -> 选择Web -> 选择ASP.NET应用程序 -> 命名项目 -> // 然后检查MVC并选择空项目

在项目中添加一个控制器,并为其创建视图。然后在控制器中编写以下代码:

// CustomerController类的实现 public class CustomerController : Controller { ICustomerRepository _CustomerRepo; public CustomerController(ICustomerRepository customerRepo) { _CustomerRepo = customerRepo; } // GET: /Customer/ public ActionResult Index() { List<Customer> model = (List<Customer>)_CustomerRepo.SelectAll(); return View(model); } public ActionResult Insert(Customer obj) { _CustomerRepo.Insert(obj); _CustomerRepo.Save(); return View(); } public ActionResult Edit(string id) { Customer existing = _CustomerRepo.SelectByID(id); return View(existing); } public ActionResult ConfirmDelete(string id) { Customer existing = _CustomerRepo.SelectByID(id); return View(existing); } public ActionResult Delete(string id) { _CustomerRepo.Delete(id); _CustomerRepo.Save(); return View(); } }

配置Autofac

在App_Start文件夹中添加一个名为AutofacConfig.cs的静态类,并在Global.asax中调用这个类的方法。

// AutofacConfig类的实现 public static class AutofacConfig { public static void RegisterComponents() { var builder = new ContainerBuilder(); builder.RegisterType<CustomerRepository>().As<ICustomerRepository>(); builder.RegisterType<CustomerController>(); builder.RegisterType<Northwind_DBEntities>().As<INorthwind_DBEntities>(); var container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); } } // Application类的实现 public class Application : System.Web.HttpApplication { protected void Application_Start() { AutofacConfig.RegisterComponents(); AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485