.NET Framework 4.8中用Unity实现.NET Core配置注入等效方案
在.NET Framework 4.8 + Unity容器中实现类似.NET Core的配置绑定注入
背景场景
我正在查看一段.NET Core应用程序代码,其中通过配置文件绑定并注入FictionalRepositoryOptions类,具体实现如下:
Program.cs
builder.Services.Configure<FictionalRepositoryOptions>( builder.Configuration.GetSection(FictionalRepositoryOptions.Name) );
FictionalRepositoryOptions.cs
public class FictionalRepositoryOptions { /// <summary>配置文件中对应的节点名称</summary> public const string Name = "FictionalRepository"; /// <summary>基础认证密钥</summary> public string Secret { get; init; } = String.Empty; }
appsettings.json 配置
"FictionalRepository": { "Secret": "secret value here" },
之后该类可通过构造函数注入并使用,示例:
public Service(string baseUrl, FictionalRepositoryOptions options) { var auth = new AuthenticationHeaderValue("Bearer", options.Secret); }
请问在.NET Framework 4.8中,使用Unity容器是否有优雅的等效实现方式?
解决方案
当然有,以下是几种实用的实现方式:
方式一:直接绑定配置并注册(推荐)
首先通过NuGet安装Microsoft.Extensions.Configuration.Json和Microsoft.Extensions.Configuration.Binder包,然后按以下步骤操作:
- 构建配置读取对象
在Unity容器初始化的代码(比如Global.asax或者专门的容器配置类)中读取配置文件:
var configBuilder = new ConfigurationBuilder() .SetBasePath(AppDomain.CurrentDomain.BaseDirectory) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); IConfigurationRoot configuration = configBuilder.Build();
- 绑定配置并注册到Unity
将绑定后的配置实例注册为单例,确保注入时始终拿到同一个配置对象:
var repoOptions = configuration.GetSection(FictionalRepositoryOptions.Name) .Get<FictionalRepositoryOptions>(); container.RegisterInstance<FictionalRepositoryOptions>(repoOptions);
也可以用更简洁的写法,直接在注册逻辑里完成绑定:
container.RegisterType<FictionalRepositoryOptions>(new InjectionFactory(_ => configuration.GetSection(FictionalRepositoryOptions.Name).Get<FictionalRepositoryOptions>() ));
方式二:封装Unity扩展(多配置类场景)
如果项目中有大量配置类需要绑定,可以封装一个Unity扩展来批量处理:
public class ConfigurationBindingExtension : UnityContainerExtension { private readonly IConfiguration _configuration; public ConfigurationBindingExtension(IConfiguration configuration) { _configuration = configuration; } protected override void Initialize() { // 批量注册配置类 RegisterConfig<FictionalRepositoryOptions>(); // 可在此添加更多配置类的注册 } private void RegisterConfig<T>() where T : class, new() { // 尝试读取类中定义的Name常量,没有则用类名作为配置节点名 var configSectionName = typeof(T).GetField("Name")?.GetValue(null) as string ?? typeof(T).Name; var configInstance = _configuration.GetSection(configSectionName).Get<T>() ?? new T(); Container.RegisterInstance(configInstance); } }
然后在初始化Unity时启用这个扩展:
var configuration = new ConfigurationBuilder() .SetBasePath(AppDomain.CurrentDomain.BaseDirectory) .AddJsonFile("appsettings.json") .Build(); container.AddExtension(new ConfigurationBindingExtension(configuration));
使用方式
和.NET Core完全一致,直接在构造函数中注入配置类即可:
public Service(string baseUrl, FictionalRepositoryOptions options) { var auth = new AuthenticationHeaderValue("Bearer", options.Secret); }
内容的提问来源于stack exchange,提问作者Code Vader
相关产品推荐
相关产品推荐

