.NET Core类库中如何自动注册DI服务?无需宿主手动注册
类库内自动完成服务注册的实现方案
如果不想让类库使用者手动调用服务扩展方法,你可以通过以下几种方式在类库内部完成服务的自动注册与容器初始化:
方案1:静态服务容器+模块初始化(推荐.NET 5+)
利用.NET 5及以上支持的模块初始化器,在类库被加载时自动完成服务注册并初始化静态服务容器,使用者直接通过类库提供的静态方法获取服务即可。
实现代码:
// 服务定义 public interface IClient { void DoWork(); } public class Client : IClient { public void DoWork() => Console.WriteLine("Client is working"); } // 模块初始化器+静态容器 public static class LibraryServiceContainer { public static IServiceProvider ServiceProvider { get; private set; } // .NET 5+ 模块初始化特性,类库加载时自动执行 [ModuleInitializer] public static void Initialize() { var services = new ServiceCollection(); // 类库内部完成服务注册 services.AddSingleton<IClient, Client>(); ServiceProvider = services.BuildServiceProvider(); } // 对外提供获取服务的方法 public static T GetService<T>() where T : notnull { return ServiceProvider.GetRequiredService<T>(); } }
使用者调用方式:
// 使用者无需手动注册,直接调用 var client = LibraryServiceContainer.GetService<IClient>(); client.DoWork();
方案2:预配置的主机工厂
类库提供一个封装好的主机创建方法,内部已完成服务注册,使用者直接通过这个方法获取主机或服务,无需自己配置服务集合。
实现代码:
public static class LibraryHostFactory { public static IHost CreateLibraryHost() { return Host.CreateDefaultBuilder() .ConfigureServices(services => { // 类库内部注册服务 services.AddSingleton<IClient, Client>(); }) .Build(); } }
使用者调用方式:
using var host = LibraryHostFactory.CreateLibraryHost(); var client = host.Services.GetRequiredService<IClient>(); client.DoWork();
注意事项
- 静态容器方案要注意线程安全,模块初始化器是线程安全的,无需额外处理;
- 如果类库需要支持多实例场景,静态容器方案可能不适用,此时推荐预配置主机工厂;
- 避免在类库中过度依赖静态容器,否则会降低代码的可测试性,必要时仍需保留扩展方法供使用者自定义注册。
内容的提问来源于stack exchange,提问作者shah Taymur
相关产品推荐
相关产品推荐

