.NET三大框架设计模式全解析

.NET三大框架设计模式全解析

引言

设计模式是软件开发中经过验证的、可复用的解决方案,用于解决特定上下文中反复出现的问题。在.NET生态系统中,许多框架都采用了各种设计模式来提高代码的可维护性、可扩展性和可测试性。本文将详细探讨ASP.NET Core、Entity Framework和WPF这三个主流框架中常见的设计模式应用,帮助开发者更好地理解和应用这些模式。

文章目录

引言ASP.NET Core中的设计模式1. 依赖注入(Dependency Injection)模式2. 中介者(Mediator)模式3. 管道(Pipeline)模式4. 选项(Options)模式

Entity Framework Core中的设计模式1. 仓储(Repository)与工作单元(Unit of Work)模式2. 规约(Specification)模式3. 领域驱动设计(DDD)模式

WPF中的设计模式1. MVVM(Model-View-ViewModel)模式2. 命令(Command)模式3. 观察者(Observer)模式4. 装饰器(Decorator)模式

总结与实践建议参考资料

ASP.NET Core中的设计模式

ASP.NET Core是一个跨平台、高性能的开源框架,用于构建现代化的云端应用。其架构中融入了多种设计模式,使开发人员能够构建灵活且可维护的应用程序。

1. 依赖注入(Dependency Injection)模式

依赖注入是ASP.NET Core的核心特性,框架本身就内置了DI容器。

// 在Startup.cs或Program.cs中注册服务

public void ConfigureServices(IServiceCollection services)

{

// 注册服务的生命周期

services.AddTransient(); // 每次请求创建新实例

services.AddScoped(); // 每个HTTP请求内共享一个实例

services.AddSingleton(); // 应用程序生命周期内共享一个实例

}

// 在控制器中通过构造函数注入

public class HomeController : Controller

{

private readonly ITransientService _transientService;

// 依赖通过构造函数注入

public HomeController(ITransientService transientService)

{

_transientService = transientService; // 控制器不需要知道具体实现

}

}

优势:

降低组件间的耦合度提高代码的可测试性简化配置管理提高代码的可维护性和可扩展性

2. 中介者(Mediator)模式

ASP.NET Core中常见的MediatR库实现了中介者模式,用于处理请求/响应和事件通知。

// 定义请求和处理程序

public class GetCustomerQuery : IRequest

{

public int CustomerId { get; set; }

}

public class GetCustomerQueryHandler : IRequestHandler

{

private readonly ICustomerRepository _repository;

public GetCustomerQueryHandler(ICustomerRepository repository)

{

_repository = repository;

}

public async Task Handle(GetCustomerQuery request, CancellationToken cancellationToken)

{

// 处理查询逻辑

var customer = await _repository.GetByIdAsync(request.CustomerId);

return new CustomerDto { Id = customer.Id, Name = customer.Name };

}

}

// 在控制器中使用

public class CustomerController : Controller

{

private readonly IMediator _mediator;

public CustomerController(IMediator mediator)

{

_mediator = mediator;

}

public async Task GetCustomer(int id)

{

// 发送请求到中介者,由中介者找到合适的处理程序

var customer = await _mediator.Send(new GetCustomerQuery { CustomerId = id });

return View(customer);

}

}

优势:

解耦请求的发送者和接收者简化复杂的业务逻辑支持横切关注点(如日志记录、缓存等)

3. 管道(Pipeline)模式

ASP.NET Core中间件是典型的管道模式应用,请求通过一系列组件顺序处理。

public void Configure(IApplicationBuilder app)

{

// 管道中的每个中间件按顺序处理请求

app.UseExceptionHandler("/Error");

app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();

app.UseAuthorization();

app.UseEndpoints(endpoints =>

{

endpoints.MapControllerRoute(

name: "default",

pattern: "{controller=Home}/{action=Index}/{id?}");

});

}

优势:

可以灵活地添加或移除处理步骤每个中间件只关注特定职责提高代码的可维护性和可测试性

4. 选项(Options)模式

ASP.NET Core使用选项模式来配置服务行为。

// 定义选项类

public class EmailSettings

{

public string SmtpServer { get; set; }

public int Port { get; set; }

public string Username { get; set; }

public string Password { get; set; }

}

// 注册选项

public void ConfigureServices(IServiceCollection services)

{

services.Configure(Configuration.GetSection("EmailSettings"));

}

// 在服务中使用选项

public class EmailService

{

private readonly EmailSettings _settings;

public EmailService(IOptions options)

{

_settings = options.Value;

}

public void SendEmail(string to, string subject, string body)

{

// 使用_settings中的配置

}

}

优势:

集中管理配置强类型配置访问支持运行时更新配置

Entity Framework Core中的设计模式

Entity Framework Core是.NET的现代化ORM框架,它也采用了多种设计模式来简化数据访问层的开发。

1. 仓储(Repository)与工作单元(Unit of Work)模式

仓储模式封装数据访问逻辑,工作单元模式管理事务一致性。

// 仓储接口

public interface ICustomerRepository

{

Task GetByIdAsync(int id);

Task> GetAllAsync();

Task AddAsync(Customer customer);

Task UpdateAsync(Customer customer);

Task DeleteAsync(int id);

}

// 工作单元接口

public interface IUnitOfWork

{

ICustomerRepository Customers { get; }

IOrderRepository Orders { get; }

Task SaveChangesAsync();

}

// EF Core实现

public class CustomerRepository : ICustomerRepository

{

private readonly AppDbContext _context;

public CustomerRepository(AppDbContext context)

{

_context = context;

}

public async Task GetByIdAsync(int id)

{

return await _context.Customers.FindAsync(id);

}

// 实现其他方法...

}

public class UnitOfWork : IUnitOfWork

{

private readonly AppDbContext _context;

private ICustomerRepository _customerRepository;

private IOrderRepository _orderRepository;

public UnitOfWork(AppDbContext context)

{

_context = context;

}

public ICustomerRepository Customers =>

_customerRepository ??= new CustomerRepository(_context);

public IOrderRepository Orders =>

_orderRepository ??= new OrderRepository(_context);

public async Task SaveChangesAsync()

{

return await _context.SaveChangesAsync();

}

}

优势:

隔离数据访问逻辑,提高可测试性确保事务一致性提供统一的数据访问API

2. 规约(Specification)模式

规约模式用于封装查询条件,使它们可重用和可组合。

// 基础规约接口

public interface ISpecification

{

Expression> Criteria { get; }

List>> Includes { get; }

List IncludeStrings { get; }

Expression> OrderBy { get; }

Expression> OrderByDescending { get; }

}

// 基础规约实现

public abstract class BaseSpecification : ISpecification

{

public Expression> Criteria { get; private set; }

public List>> Includes { get; } = new List>>();

public List IncludeStrings { get; } = new List();

public Expression> OrderBy { get; private set; }

public Expression> OrderByDescending { get; private set; }

protected BaseSpecification(Expression> criteria)

{

Criteria = criteria;

}

protected void AddInclude(Expression> includeExpression)

{

Includes.Add(includeExpression);

}

protected void AddInclude(string includeString)

{

IncludeStrings.Add(includeString);

}

protected void ApplyOrderBy(Expression> orderByExpression)

{

OrderBy = orderByExpression;

}

protected void ApplyOrderByDescending(Expression> orderByDescendingExpression)

{

OrderByDescending = orderByDescendingExpression;

}

}

// 具体规约实现

public class CustomerWithOrdersSpecification : BaseSpecification

{

public CustomerWithOrdersSpecification(int customerId)

: base(c => c.Id == customerId)

{

AddInclude(c => c.Orders);

}

}

// 在仓储中使用规约

public interface IRepository where T : class

{

Task GetByIdAsync(int id);

Task> ListAllAsync();

Task> ListAsync(ISpecification spec);

Task FirstOrDefaultAsync(ISpecification spec);

}

public class Repository : IRepository where T : class

{

protected readonly DbContext _dbContext;

public Repository(DbContext dbContext)

{

_dbContext = dbContext;

}

public async Task> ListAsync(ISpecification spec)

{

return await ApplySpecification(spec).ToListAsync();

}

private IQueryable ApplySpecification(ISpecification spec)

{

var query = _dbContext.Set().AsQueryable();

if (spec.Criteria != null)

query = query.Where(spec.Criteria);

query = spec.Includes.Aggregate(query, (current, include) => current.Include(include));

query = spec.IncludeStrings.Aggregate(query, (current, include) => current.Include(include));

if (spec.OrderBy != null)

query = query.OrderBy(spec.OrderBy);

else if (spec.OrderByDescending != null)

query = query.OrderByDescending(spec.OrderByDescending);

return query;

}

// 实现其他方法...

}

优势:

使查询条件可复用和组合提高代码可读性和可维护性支持复杂查询的构建

3. 领域驱动设计(DDD)模式

Entity Framework Core可以与DDD模式一起使用,构建富领域模型。

// 实体基类

public abstract class Entity

{

public int Id { get; protected set; }

protected Entity() { }

public override bool Equals(object obj)

{

var entity = obj as Entity;

if (entity == null) return false;

return Id == entity.Id;

}

public override int GetHashCode()

{

return Id.GetHashCode();

}

}

// 值对象

public class Address : ValueObject

{

public string Street { get; private set; }

public string City { get; private set; }

public string State { get; private set; }

public string Country { get; private set; }

public string ZipCode { get; private set; }

private Address() { } // EF Core需要

public Address(string street, string city, string state, string country, string zipCode)

{

Street = street;

City = city;

State = state;

Country = country;

ZipCode = zipCode;

}

protected override IEnumerable GetEqualityComponents()

{

yield return Street;

yield return City;

yield return State;

yield return Country;

yield return ZipCode;

}

}

// 聚合根

public class Order : Entity, IAggregateRoot

{

private readonly List _orderItems = new List();

public IReadOnlyCollection OrderItems => _orderItems.AsReadOnly();

public decimal TotalAmount => _orderItems.Sum(i => i.UnitPrice * i.Quantity);

public OrderStatus Status { get; private set; }

public CustomerId CustomerId { get; private set; }

public Address ShippingAddress { get; private set; }

private Order() { } // EF Core需要

public Order(CustomerId customerId, Address shippingAddress)

{

CustomerId = customerId;

ShippingAddress = shippingAddress;

Status = OrderStatus.Created;

}

public void AddOrderItem(ProductId productId, decimal unitPrice, int quantity)

{

// 领域逻辑:检查产品是否已存在

var existingItem = _orderItems.SingleOrDefault(i => i.ProductId == productId);

if (existingItem != null)

{

// 更新现有项目数量

existingItem.UpdateQuantity(existingItem.Quantity + quantity);

}

else

{

// 添加新项目

_orderItems.Add(new OrderItem(productId, unitPrice, quantity));

}

}

public void Confirm()

{

// 领域逻辑:确认订单

if (Status != OrderStatus.Created)

throw new OrderDomainException("只能确认处于'已创建'状态的订单");

Status = OrderStatus.Confirmed;

}

}

// DbContext配置

public class AppDbContext : DbContext

{

public AppDbContext(DbContextOptions options) : base(options) { }

public DbSet Orders { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)

{

// 配置值对象为拥有的实体

modelBuilder.Entity()

.OwnsOne(o => o.ShippingAddress);

// 配置一对多关系

modelBuilder.Entity()

.HasMany(o => o.OrderItems)

.WithOne()

.IsRequired();

// 其他配置...

}

}

优势:

将业务规则封装在领域模型中使用强类型的值对象增强类型安全支持聚合边界以确保数据一致性

WPF中的设计模式

Windows Presentation Foundation (WPF)是用于创建桌面应用的UI框架,它也充分利用了各种设计模式。

1. MVVM(Model-View-ViewModel)模式

MVVM是WPF应用程序中最常用的架构模式,它将应用程序分为三层:Model(模型)、View(视图)和ViewModel(视图模型)。

// Model - 表示数据和业务逻辑

public class Customer : INotifyPropertyChanged

{

private string _name;

public string Name

{

get => _name;

set

{

if (_name != value)

{

_name = value;

OnPropertyChanged(nameof(Name));

}

}

}

// INotifyPropertyChanged实现

public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged(string propertyName)

{

PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

}

}

// ViewModel - 适配Model供View使用,并提供命令

public class CustomerViewModel : INotifyPropertyChanged

{

private Customer _customer;

public CustomerViewModel(Customer customer)

{

_customer = customer;

SaveCommand = new RelayCommand(Save, CanSave);

}

public string Name

{

get => _customer.Name;

set

{

if (_customer.Name != value)

{

_customer.Name = value;

OnPropertyChanged(nameof(Name));

}

}

}

public ICommand SaveCommand { get; }

private bool CanSave()

{

return !string.IsNullOrWhiteSpace(Name);

}

private void Save()

{

// 保存客户数据

}

// INotifyPropertyChanged实现

public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged(string propertyName)

{

PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

}

}

// View - XAML界面

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="Customer" Height="300" Width="400">