.NET Core 2.0模块化依赖注入:构建类EF的核心扩展库结构
我来帮你拆解怎么实现这种类似EF的核心+扩展包结构,结合依赖注入来注册特定实现——咱们以你提到的影片生成器框架为例一步步来:
1. 先搭建核心包的基础结构
核心包的核心是定义抽象契约和通用逻辑,不能包含任何具体实现,这样才能让扩展包基于它做定制化开发。
比如我们先定义影片生成器的抽象接口、核心服务类,还有通用配置选项:
// 核心包:VideoGenerator.Core namespace VideoGenerator.Core; // 抽象的影片生成器接口,所有扩展包都要实现这个契约 public interface IVideoGenerator { Task<byte[]> GenerateVideoAsync(VideoGenerationOptions options); } // 核心服务类,依赖抽象接口,封装通用逻辑(比如参数校验、日志) public class VideoGeneratorHost { private readonly IVideoGenerator _generator; public VideoGeneratorHost(IVideoGenerator generator) { _generator = generator ?? throw new ArgumentNullException(nameof(generator)); } public async Task<byte[]> GenerateVideo(VideoGenerationOptions options) { // 通用前置逻辑:参数校验 if (options.Duration <= TimeSpan.Zero) throw new ArgumentException("视频时长必须大于0", nameof(options.Duration)); // 委托给具体实现执行生成逻辑 return await _generator.GenerateVideoAsync(options); } } // 通用配置选项类,类似EF的DbContextOptions,承载所有扩展包都能用到的配置 public class VideoGenerationOptions { public TimeSpan Duration { get; set; } public string Resolution { get; set; } = "1080p"; // 可以添加更多通用配置项,比如帧率、水印路径等 }
2. 构建扩展包(以MP4生成器为例)
扩展包需要引用核心包,实现IVideoGenerator接口,同时提供DI注册的扩展方法——这一步就类似EF的UseSqlServer,让用户可以轻松把特定实现注入到容器中。
// 扩展包:VideoGenerator.Mp4Provider namespace VideoGenerator.Mp4Provider; // 具体的MP4生成器实现,依赖自己的专属配置 public class Mp4VideoGenerator : IVideoGenerator { private readonly Mp4GenerationOptions _mp4Options; public Mp4VideoGenerator(Mp4GenerationOptions mp4Options) { _mp4Options = mp4Options; } public async Task<byte[]> GenerateVideoAsync(VideoGenerationOptions options) { // 这里写具体的MP4生成逻辑,比如调用FFmpeg、第三方视频处理库 Console.WriteLine($"生成MP4视频:时长{options.Duration},分辨率{options.Resolution},编码格式{_mp4Options.Codec}"); await Task.Delay(1000); // 模拟耗时生成操作 return new byte[1024]; // 模拟生成的视频字节流 } } // 扩展包专属配置,继承通用选项,添加MP4特有的配置项 public class Mp4GenerationOptions : VideoGenerationOptions { public string Codec { get; set; } = "H.264"; public int Bitrate { get; set; } = 5000; // 比特率(kbps) } // DI扩展方法,让用户可以像EF那样流畅注册扩展包 public static class VideoGeneratorServiceCollectionExtensions { public static IServiceCollection AddMp4VideoGenerator( this IServiceCollection services, Action<Mp4GenerationOptions> configureOptions) { if (services == null) throw new ArgumentNullException(nameof(services)); if (configureOptions == null) throw new ArgumentNullException(nameof(configureOptions)); // 注册并配置扩展包的专属选项 services.Configure(configureOptions); // 注册具体的生成器实现到DI容器 services.AddScoped<IVideoGenerator, Mp4VideoGenerator>(); // 注册核心服务类 services.AddScoped<VideoGeneratorHost>(); return services; } }
3. 在应用中注册和使用
这一步就和你用EF时注册SQL提供器的体验完全一致——只需要调用扩展方法,传入配置即可:
// 比如ASP.NET Core应用的Program.cs var builder = WebApplication.CreateBuilder(args); // 注册MP4生成器,传入自定义配置,和EF的builder.Services.AddDbContext<MyDbContext>(options => options.UseSqlServer(...))逻辑一致 builder.Services.AddMp4VideoGenerator(options => { options.Duration = TimeSpan.FromSeconds(30); options.Resolution = "4K"; options.Codec = "H.265"; // 用更高压缩率的编码 options.Bitrate = 8000; }); var app = builder.Build(); // 使用核心服务生成视频 using var scope = app.Services.CreateScope(); var videoHost = scope.ServiceProvider.GetRequiredService<VideoGeneratorHost>(); var videoBytes = await videoHost.GenerateVideo(new VideoGenerationOptions()); app.Run();
4. 扩展更多生成器的思路
如果后续要加WebM、AVI等格式的生成器,只需要重复扩展包的流程:
- 新建扩展包(比如
VideoGenerator.WebmProvider) - 实现
IVideoGenerator接口 - 定义自己的
WebmGenerationOptions和DI扩展方法AddWebmVideoGenerator - 应用端只需要把注册代码从
AddMp4VideoGenerator改成AddWebmVideoGenerator,核心逻辑完全不用修改
关键设计要点
- 核心包只做抽象:保证核心逻辑稳定,扩展包可以独立迭代;
- 配置分层:通用配置+扩展专属配置,兼顾灵活性和易用性;
- DI扩展方法:提供流畅的API,让用户像使用EF一样轻松切换实现;
- 依赖倒置:核心服务依赖抽象接口,而不是具体实现,符合SOLID原则。
内容的提问来源于stack exchange,提问作者agdelen
相关产品推荐
相关产品推荐

