Pure.DI与ASP.NET Core集成:Web API与MVC项目配置完整指南
【免费下载链接】Pure.DIPure DI for .NET项目地址: https://gitcode.com/gh_mirrors/pu/Pure.DI
如何在ASP.NET Core项目中高效集成Pure.DI依赖注入框架?本文将为您提供完整的配置指南,帮助您在Web API和MVC项目中实现编译时依赖注入的最佳实践。Pure.DI作为.NET平台的编译时依赖注入框架,能够显著提升应用程序的性能和类型安全性。
为什么选择Pure.DI进行ASP.NET Core集成?
Pure.DI通过编译时生成依赖注入代码,彻底消除了传统DI容器在运行时的反射开销。这种设计带来了几个关键优势:
- 零运行时开销:所有依赖解析逻辑在编译时确定
- 完全类型安全:编译时验证所有依赖关系
- 更好的性能:直接生成
new表达式,无需反射 - 编译时错误检测:依赖问题在编译时即可发现
基础集成配置步骤
1. 安装必要的NuGet包
首先,在您的ASP.NET Core项目中添加Pure.DI的核心包和ASP.NET Core集成包:
<PackageReference Include="Pure.DI" Version="2.4.3" PrivateAssets="all" /> <PackageReference Include="Pure.DI.MS" Version="2.4.3" />2. 创建Composition类
创建继承自ServiceProviderFactory<T>的Composition类,这是Pure.DI与ASP.NET Core集成的核心:
using Pure.DI; using Pure.DI.MS; using static Pure.DI.Lifetime; namespace WebAPI; partial class Composition : ServiceProviderFactory<Composition> { [Conditional("DI")] private static void Setup() => DI.Setup() .Roots<ControllerBase>() .Bind().As(Singleton).To<ClockViewModel>() .Bind().To<ClockModel>() .Bind().As(Singleton).To<Ticks>() .Bind().To<MicrosoftLoggerAdapter<TT>>() .Bind().To<CurrentThreadDispatcher>(); }3. 配置Program.cs
在ASP.NET Core的启动代码中配置Pure.DI作为服务提供者工厂:
var builder = WebApplication.CreateBuilder(args); using var composition = new Composition(); // 使用Composition作为替代的IServiceProviderFactory builder.Host.UseServiceProviderFactory(composition); // 对于Web API项目 builder.Services.AddControllers().AddControllersAsServices(); // 对于MVC项目 builder.Services.AddControllersWithViews().AddControllersAsServices(); var app = builder.Build(); // ... 中间件配置 app.Run();Web API项目详细配置
控制器自动注册
Pure.DI通过.Roots<ControllerBase>()方法自动注册所有控制器:
[Route("[controller]")] public class ClockController( ILogger<ClockController> logger, IAppViewModel app, IClockViewModel clock) : ControllerBase { [HttpGet] public Task<ClockResult> GetDateTime() { logger.LogInformation(nameof(GetDateTime)); return Task.FromResult(new ClockResult(app.Title, clock.Date, clock.Time)); } }生命周期管理
Pure.DI支持多种生命周期配置:
// 单例模式 .Bind().As(Singleton).To<ClockViewModel>() // 瞬态模式 .Bind().To<ClockModel>() // 作用域模式 .Bind().As(Scoped).To<DbContext>()MVC项目集成要点
视图模型注入
在MVC项目中,您可以轻松注入视图模型:
public class HomeController( ILogger<HomeController> logger, IClockViewModel clockViewModel) : Controller { public IActionResult Index() { ViewBag.Date = clockViewModel.Date; ViewBag.Time = clockViewModel.Time; return View(); } }服务配置
确保正确配置MVC服务:
var builder = WebApplication.CreateBuilder(args); // 添加MVC服务并注册控制器为服务 builder.Services.AddControllersWithViews().AddControllersAsServices(); using var composition = new Composition(); builder.Host.UseServiceProviderFactory(composition); var app = builder.Build(); // 配置路由 app.MapControllerRoute( "default", "{controller=Home}/{action=Index}/{id?}"); app.Run();Minimal API集成方案
对于Minimal API项目,Pure.DI提供了更灵活的集成方式:
using var composition = new Composition(); var builder = WebApplication.CreateBuilder(args); builder.Host.UseServiceProviderFactory(composition); var app = builder.Build(); // 创建应用程序组合根 using var root = composition.Root; root.Value.Run(app); partial class Program( IClockViewModel clock, IAppViewModel appModel) { private void Run(WebApplication app) { app.MapGet("/", ( [FromServices] ILogger<Program> logger) => { logger.LogInformation("开始请求执行"); return new ClockResult(appModel.Title, clock.Date, clock.Time); }); app.Run(); } }高级配置技巧
1. 混合依赖注入策略
Pure.DI可以与Microsoft DI容器协同工作:
var builder = WebApplication.CreateBuilder(args); // 使用Pure.DI作为主要DI容器 using var composition = new Composition(); builder.Host.UseServiceProviderFactory(composition); // 同时使用Microsoft DI注册特定服务 builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("Default"))); builder.Services.AddAuthentication(); builder.Services.AddAuthorization();2. 作用域生命周期管理
对于需要请求作用域的服务,使用Scoped生命周期:
partial class Composition : ServiceProviderFactory<Composition> { [Conditional("DI")] private static void Setup() => DI.Setup() .Hint(Hint.ScopeMethodName, "SetupScope") .Bind().As(Scoped).To<RequestContext>() .Bind().As(Singleton).To<Configuration>() .Root<ICheckoutService>("RequestRoot"); }3. 泛型依赖支持
Pure.DI完全支持泛型类型依赖:
.Bind<IRepository<TT>>().To<Repository<TT>>() .Bind<IService<TT>>().To<Service<TT>>() .Root<IDataService>("DataService")常见问题解决方案
问题1:控制器无法解析
解决方案:确保使用.AddControllersAsServices()注册控制器:
builder.Services.AddControllers().AddControllersAsServices();并在Composition类中注册控制器根:
.Roots<ControllerBase>()问题2:作用域服务管理
解决方案:使用Owned<T>包装器管理作用域生命周期:
.Root<Owned<Program>>(nameof(Root))问题3:与第三方库集成
解决方案:通过ServiceProviderFactory<T>基类实现桥接:
partial class Composition : ServiceProviderFactory<Composition> { // Pure.DI无法解析的服务会委托给Microsoft DI }性能优化建议
1. 禁用Resolve方法
对于生产环境,禁用Resolve方法以减少生成代码大小:
.Hint(Hint.Resolve, "Off")2. 使用编译时验证
利用Pure.DI的编译时验证特性,确保所有依赖在编译时都是有效的。
3. 合理使用生命周期
- 单例服务:配置信息、日志记录器
- 作用域服务:数据库上下文、请求特定数据
- 瞬态服务:轻量级、无状态服务
实际项目结构示例
典型的ASP.NET Core项目结构:
src/ ├── WebAPI/ │ ├── Composition.cs # Pure.DI配置 │ ├── Program.cs # 启动配置 │ ├── Controllers/ │ │ └── ClockController.cs │ ├── Services/ │ │ ├── IClockService.cs │ │ └── ClockService.cs │ └── ViewModels/ │ └── ClockViewModel.cs ├── Core/ │ ├── Models/ │ └── Interfaces/ └── Infrastructure/ └── Persistence/测试与调试
单元测试配置
在测试项目中配置Pure.DI:
[TestClass] public class ClockControllerTests { private Composition _composition; [TestInitialize] public void Setup() { _composition = new Composition(); } [TestMethod] public void GetDateTime_ReturnsValidResult() { var controller = _composition.Resolve<ClockController>(); // 测试逻辑 } }调试技巧
- 使用
.ToString()方法查看依赖图 - 启用详细日志记录
- 使用编译时错误信息定位问题
最佳实践总结
- 明确的生命周期管理:根据服务特性选择合适的生命周期
- 控制器作为根:确保所有控制器都通过
.Roots<ControllerBase>()注册 - 混合使用策略:Pure.DI处理业务逻辑,Microsoft DI处理框架服务
- 编译时验证:充分利用Pure.DI的编译时类型安全检查
- 适当的性能优化:根据项目规模调整配置
通过本文的指南,您应该能够在ASP.NET Core Web API和MVC项目中成功集成Pure.DI。这种集成方式不仅提供了更好的性能,还通过编译时验证确保了应用程序的可靠性。记住,正确的依赖注入配置是构建可维护、可测试应用程序的关键。
无论您是从头开始新项目,还是将现有项目迁移到Pure.DI,遵循这些配置步骤和最佳实践都将帮助您构建更高效、更可靠的.NET应用程序。
【免费下载链接】Pure.DIPure DI for .NET项目地址: https://gitcode.com/gh_mirrors/pu/Pure.DI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考