如何在ASP.NET Core 3.1内置DI中注册供公共控制器使用的internal接口
核心原因
你触发报错的直接原因是RonaldoContainer构造函数依赖的IRonaldo服务没有被注册到DI容器中,和IRonaldo是internal类型没有直接关系——ASP.NET Core内置DI完全可以解析internal类型的服务,只要注册时所在的代码上下文有权限访问这些internal类型即可。
推荐实现方案
完全满足隐藏实现细节+内置DI直接使用的要求,步骤如下:
- 第一步:在你的Nuget类库项目中,新增公共的
IServiceCollection扩展方法,在该方法内同时注册对外公开的IRonaldoContainer和内部的IRonaldo、Ronaldo服务:
using Microsoft.Extensions.DependencyInjection; public static class RonaldoContainerServiceExtensions { public static IServiceCollection AddRonaldoContainer(this IServiceCollection services) { // 注册内部实现,只有当前类库能访问这些internal类型,外部无感知 services.AddScoped<IRonaldo, Ronaldo>(); // 注册对外公开的服务 services.AddScoped<IRonaldoContainer, RonaldoContainer>(); return services; } }
- 第二步:在ASP.NET Core应用的服务注册入口(
Program.cs或Startup.cs)中调用该扩展方法完成注册即可,业务项目无需额外处理internal类型:
// .NET 6+ 顶层语句写法示例 var builder = WebApplication.CreateBuilder(args); // 其他服务注册逻辑... builder.Services.AddRonaldoContainer(); // 其他配置逻辑... var app = builder.Build(); // 中间件配置逻辑... app.Run();
可选补充说明
如果你的Nuget包有多个程序集拆分、注册扩展方法所在的程序集不能直接访问internal类型,可以在实现类所在的程序集的AssemblyInfo.cs中添加程序集可见性配置,仅把internal权限开放给注册扩展所在的程序集:
// 替换为你注册扩展方法所在的程序集名称即可 [assembly: InternalsVisibleTo("YourNugetPackage.RegistrationAssembly")]
该配置不会把internal类型暴露给引用Nuget的业务项目,不会污染公共API。
内容的提问来源于stack exchange,提问作者Avihai Sudai
相关产品推荐
相关产品推荐

