在现代 C# 开发中,尤其是使用 .NET Core 或 .NET 5+ 构建应用程序时,依赖注入(Dependency Injection, DI)已成为标准实践。而装饰器模式(Decorator Pattern)则是一种强大的设计模式,用于在不修改原始类的前提下动态地为对象添加行为。当我们将两者结合——即通过依赖注入容器实现服务装饰器的嵌套(或称链式装饰)——就能构建出高度可扩展、可维护且松耦合的系统。
本文将手把手教你如何在 C# 中利用 .NET 的内置依赖注入容器实现装饰器嵌套,即使你是编程新手也能轻松上手!
装饰器模式允许你通过将对象放入包含行为的特殊包装器(即“装饰器”)中来为对象添加新功能。这些装饰器与被装饰的对象实现相同的接口,因此可以透明地替换原始对象。
在实际项目中,我们常常需要为某个服务添加日志记录、缓存、权限验证、性能监控等功能。如果把这些逻辑硬编码到服务类中,会导致代码臃肿、难以测试和复用。而通过依赖注入注册多个装饰器,我们可以像搭积木一样灵活组合功能。
假设我们要实现一个简单的消息发送服务 IMessageService,并为其添加日志和性能计时两个装饰器。
public interface IMessageService{ string SendMessage(string message);} public class EmailMessageService : IMessageService{ public string SendMessage(string message) { // 模拟发送邮件 return $"[Email] Sent: {message}"; }} public class LoggingDecorator : IMessageService{ private readonly IMessageService _innerService; private readonly ILogger<LoggingDecorator> _logger; public LoggingDecorator(IMessageService innerService, ILogger<LoggingDecorator> logger) { _innerService = innerService; _logger = logger; } public string SendMessage(string message) { _logger.LogInformation($"Sending message: {message}"); var result = _innerService.SendMessage(message); _logger.LogInformation($"Message sent successfully: {result}"); return result; }} public class TimingDecorator : IMessageService{ private readonly IMessageService _innerService; private readonly ILogger<TimingDecorator> _logger; public TimingDecorator(IMessageService innerService, ILogger<TimingDecorator> logger) { _innerService = innerService; _logger = logger; } public string SendMessage(string message) { var stopwatch = System.Diagnostics.Stopwatch.StartNew(); var result = _innerService.SendMessage(message); stopwatch.Stop(); _logger.LogInformation($"SendMessage took {stopwatch.ElapsedMilliseconds} ms"); return result; }} .NET 的内置 DI 容器不直接支持自动装饰器注册,但我们可以通过工厂委托手动构建嵌套链:
// Program.cs (.NET 6+ Minimal API 风格)var builder = WebApplication.CreateBuilder(args);// 注册基础服务builder.Services.AddSingleton<IMessageService, EmailMessageService>();// 手动构建装饰器链:Timing -> Logging -> Emailbuilder.Services.Decorate<IMessageService>((serviceProvider, inner) => new TimingDecorator( new LoggingDecorator(inner, serviceProvider.GetRequiredService<ILogger<LoggingDecorator>>()), serviceProvider.GetRequiredService<ILogger<TimingDecorator>>() ));// 注意:上面的 Decorate 是自定义扩展方法(见下文) 为了简化注册,我们可以创建一个通用的 Decorate 扩展方法:
public static class ServiceCollectionExtensions{ public static void Decorate<TService>(this IServiceCollection services, Func<IServiceProvider, TService, TService> decoratorFactory) where TService : class { var descriptor = services.FirstOrDefault(d => d.ServiceType == typeof(TService)); if (descriptor == null) throw new InvalidOperationException($"{typeof(TService)} is not registered."); services.Remove(descriptor); services.Add(new ServiceDescriptor( typeof(TService), provider => decoratorFactory(provider, (TService)provider.GetService(descriptor.ImplementationType)!), descriptor.Lifetime )); }} 当你注入 IMessageService 并调用 SendMessage 时,执行顺序将是:
本文深入讲解了如何在 C# 项目中实现 C#依赖注入 与 装饰器模式 的结合,并展示了 .NET Core依赖注入 容器中 服务装饰器嵌套 的完整流程。这些技术是构建企业级应用的核心技能。
通过依赖注入实现装饰器嵌套,不仅能提升代码的可读性和可维护性,还能让你的服务具备“插件式”扩展能力。虽然 .NET 内置 DI 不原生支持自动装饰,但借助简单的扩展方法,我们完全可以优雅地实现这一模式。
现在,你已经掌握了 C# 中依赖注入装饰器嵌套的核心技巧!快去你的项目中试试吧!
本文由主机测评网于2025-12-14发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025127720.html