首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >本命符阵:依赖注入与AOP的玄机真解

本命符阵:依赖注入与AOP的玄机真解

作者头像
云中小生
发布2025-08-24 09:12:04
发布2025-08-24 09:12:04
7700
代码可运行
举报
运行总次数:0
代码可运行

各位.NET道友大家好,我是.NET修仙日记掌门人,在.NET修炼之路上,许多道友初入仙门便遭遇"符阵玄机"——依赖注入(DI)面向切面编程(AOP) 。这两大法宝看似简单,实则暗藏玄机,今日便与诸位道友一同参悟其中奥妙。

DI与AOP结合架构图
DI与AOP结合架构图

DI与AOP结合架构图

一、符阵之本(依赖注入)

1.1 何谓依赖注入?

依赖注入(Dependency Injection) 如同布置符阵,将各个对象(法器)通过特定方式连接起来,而非由修炼者(类)自行锻造(创建)。

代码语言:javascript
代码运行次数:0
运行
复制
// 传统方式 - 自己锻造法器
public class Warrior
{
    private Sword _sword = new Sword();
}

// DI方式 - 由符阵提供法器
public class Warrior
{
    private IWeapon _weapon;
    public Warrior(IWeapon weapon)
    {
        _weapon = weapon;
    }
}
传统new对象 vs 依赖注入模式对比
传统new对象 vs 依赖注入模式对比

传统new对象 vs 依赖注入模式对比

1.2 .NET中的符阵核心

.NET内置了强大的依赖注入容器(符阵系统):

代码语言:javascript
代码运行次数:0
运行
复制
// 布置符阵
var services = new ServiceCollection();

// 注册法器
services.AddTransient<IWeapon, Sword>();  // 每次请求新法器
services.AddScoped<IArmor, PlateArmor>(); // 同一符阵内使用相同法器
services.AddSingleton<IShield, MagicShield>(); // 全局唯一法器

// 激活符阵
var serviceProvider = services.BuildServiceProvider();

1.3 符阵进阶技巧

  • 选项模式:可配置的符阵参数
代码语言:javascript
代码运行次数:0
运行
复制
services.Configure<WeaponOptions>(configuration.GetSection("WeaponSettings"));
  • 工厂模式:动态锻造法器
代码语言:javascript
代码运行次数:0
运行
复制
services.AddTransient<IWeapon>(sp => 
    new Sword(sp.GetRequiredService<SharpnessService>()));

二、AOP——符阵之变

2.1 何谓AOP?

AOP 原理示意图
AOP 原理示意图

AOP 原理示意图

面向切面编程(Aspect-Oriented Programming) 如同在符阵中布下禁制,在不修改原有法器的情况下,为其添加额外能力。

2.2 .NET实现AOP的三大法门

  1. 拦截器(Interceptor):
代码语言:javascript
代码运行次数:0
运行
复制
// 以Castle DynamicProxy为例
public class LoggingInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        Console.WriteLine($"调用方法: {invocation.Method.Name}");
        invocation.Proceed();
        Console.WriteLine($"方法完成: {invocation.Method.Name}");
    }
}
  1. 中间件(Middleware):
代码语言:javascript
代码运行次数:0
运行
复制
// ASP.NET Core中间件
app.Use(async (context, next) =>
{
    var stopwatch = Stopwatch.StartNew();
    await next();
    stopwatch.Stop();
    Console.WriteLine($"请求耗时: {stopwatch.ElapsedMilliseconds}ms");
});
  1. 源生成器(Source Generator):
代码语言:javascript
代码运行次数:0
运行
复制
// 编译时织入AOP逻辑
[LogAspect]
public class MyService
{
    public void DoWork() { /* ... */ }
}

2.3 AOP实战应用

  • 日志记录:自动记录方法调用
  • 性能监控:统计方法执行时间
  • 事务管理:自动开启/提交事务
  • 缓存处理:方法结果自动缓存
  • 异常处理:统一异常处理逻辑

三、符阵合璧——DI与AOP的完美结合

3.1 在DI容器中集成AOP

代码语言:javascript
代码运行次数:0
运行
复制
// 使用Scrutor扩展
services.Decorate<IOrderService, LoggingOrderServiceDecorator>();

// 或者使用Autofac
builder.RegisterType<OrderService>().As<IOrderService>()
       .EnableInterfaceInterceptors()
       .InterceptedBy(typeof(LoggingInterceptor));

3.2 实战案例:带事务和日志的订单服务

代码语言:javascript
代码运行次数:0
运行
复制
public class OrderService : IOrderService
{
    private readonly IOrderRepository _repository;
    
    public OrderService(IOrderRepository repository)
    {
        _repository = repository;
    }
    
    [Transactional]
    [LogCall]
    public async Task PlaceOrder(Order order)
    {
        await _repository.AddAsync(order);
        // 其他业务逻辑...
    }
}
实战案例时序图
实战案例时序图

实战案例时序图

终章:符阵心法

  1. 单一职责:每个法器(类)只做一件事
  2. 面向接口:依赖抽象而非具体实现
  3. 控制反转:让符阵(容器)管理对象生命周期
  4. 切面分离:横切关注点集中处理
  5. 适度使用:避免过度设计,符阵复杂反成桎梏

道友问答

Q:何时该用Transient,何时用Scoped或Singleton? A:如同选择法器使用方式:

  • Transient:一次性符咒,用完即弃
  • Scoped:同一法事(请求)中重复使用
  • Singleton:镇派之宝,全局唯一

Q:AOP会影响性能吗? A:如同禁制消耗灵力,确实有开销。但现代.NET的源生成器方案几乎零开销,可放心使用。

结语

依赖注入与AOP如同.NET修炼路上的两大符阵,掌握其玄机,方能在架构设计中游刃有余。望诸位道友勤加练习,早日参透其中奥妙!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-07-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 .NET修仙日记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、符阵之本(依赖注入)
    • 1.1 何谓依赖注入?
    • 1.2 .NET中的符阵核心
    • 1.3 符阵进阶技巧
  • 二、AOP——符阵之变
    • 2.1 何谓AOP?
    • 2.2 .NET实现AOP的三大法门
    • 2.3 AOP实战应用
  • 三、符阵合璧——DI与AOP的完美结合
    • 3.1 在DI容器中集成AOP
    • 3.2 实战案例:带事务和日志的订单服务
  • 终章:符阵心法
  • 道友问答
  • 结语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档