各位.NET道友大家好,我是.NET修仙日记掌门人,在.NET修炼之路上,许多道友初入仙门便遭遇"符阵玄机"——依赖注入(DI) 与面向切面编程(AOP) 。这两大法宝看似简单,实则暗藏玄机,今日便与诸位道友一同参悟其中奥妙。
DI与AOP结合架构图
依赖注入(Dependency Injection) 如同布置符阵,将各个对象(法器)通过特定方式连接起来,而非由修炼者(类)自行锻造(创建)。
// 传统方式 - 自己锻造法器
public class Warrior
{
private Sword _sword = new Sword();
}
// DI方式 - 由符阵提供法器
public class Warrior
{
private IWeapon _weapon;
public Warrior(IWeapon weapon)
{
_weapon = weapon;
}
}
传统new对象 vs 依赖注入模式对比
.NET内置了强大的依赖注入容器(符阵系统):
// 布置符阵
var services = new ServiceCollection();
// 注册法器
services.AddTransient<IWeapon, Sword>(); // 每次请求新法器
services.AddScoped<IArmor, PlateArmor>(); // 同一符阵内使用相同法器
services.AddSingleton<IShield, MagicShield>(); // 全局唯一法器
// 激活符阵
var serviceProvider = services.BuildServiceProvider();
services.Configure<WeaponOptions>(configuration.GetSection("WeaponSettings"));
services.AddTransient<IWeapon>(sp =>
new Sword(sp.GetRequiredService<SharpnessService>()));
AOP 原理示意图
面向切面编程(Aspect-Oriented Programming) 如同在符阵中布下禁制,在不修改原有法器的情况下,为其添加额外能力。
// 以Castle DynamicProxy为例
public class LoggingInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine($"调用方法: {invocation.Method.Name}");
invocation.Proceed();
Console.WriteLine($"方法完成: {invocation.Method.Name}");
}
}
// ASP.NET Core中间件
app.Use(async (context, next) =>
{
var stopwatch = Stopwatch.StartNew();
await next();
stopwatch.Stop();
Console.WriteLine($"请求耗时: {stopwatch.ElapsedMilliseconds}ms");
});
// 编译时织入AOP逻辑
[LogAspect]
public class MyService
{
public void DoWork() { /* ... */ }
}
// 使用Scrutor扩展
services.Decorate<IOrderService, LoggingOrderServiceDecorator>();
// 或者使用Autofac
builder.RegisterType<OrderService>().As<IOrderService>()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(LoggingInterceptor));
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);
// 其他业务逻辑...
}
}
实战案例时序图
Q:何时该用Transient,何时用Scoped或Singleton? A:如同选择法器使用方式:
Q:AOP会影响性能吗? A:如同禁制消耗灵力,确实有开销。但现代.NET的源生成器方案几乎零开销,可放心使用。
依赖注入与AOP如同.NET修炼路上的两大符阵,掌握其玄机,方能在架构设计中游刃有余。望诸位道友勤加练习,早日参透其中奥妙!