考虑以下简单的 appsettings.json:
{
"maintenanceMode": true
}
它加载在我的 Startup.cs/Configure(...) 方法中
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// Load appsettings.json config
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
_configuration = builder.Build();
// Apply static dev / production features
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
// Other features / settings
app.UseHttpsRedirection();
app.UseMvc();
}
_configuration 在 Startup.cs 中是私有(private)的,它用于将内容反序列化为结构化模型将在整个网络服务生命周期中提供附加功能:
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services) {
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddOptions();
var runtimeServices = _configuration.Get<RuntimeServices>();
services.AddSingleton(runtimeServices);
}
模型看起来像这样:
public class RuntimeServices {
[JsonProperty(PropertyName = "maintenanceMode")]
public bool MaintenanceMode { get; set; }
}
Controller 看起来像这样:
[ApiController]
public class ApplicationController : Base.Controller {
private readonly RuntimeServices _services;
public ApplicationController(IOptions<RuntimeServices> services) : base(services) {
_services = services.Value;
}
// Web-api following ...
}
问题来了:
在加载并反序列化 appsettings.json 后启动时,RuntimeServices 实例会保存所有正确的信息(是的,此处省略了其中一些信息)。
Startup.cs/ConfigureServices() 中的哈希码:
GetHashCode()
方法没有被篡改。
这会导致源自 appsettings.json 的配置未在 Controller /api 调用中应用,所有属性都使用其默认值/null 进行实例化。
我希望使用 AddSingleton()
方法可以注入(inject)非常相同 实例并在整个应用程序生命周期中重用它。有人能告诉我为什么要创建一个新的 RuntimeServices 实例吗?我如何实现在 Startup.cs 中拥有我的对象的可用实例并仍然在我的 Controller 中访问相同的对象实例的目标?
我的首选解决方案是通常的单例模式。但我希望使用 asp.net core 提供的内置功能来解决这个问题。
最佳答案
因为这个调用:
services.AddSingleton(runtimeServices);
注册 RuntimeServices
的一个实例, 它不配置 IOptions<RuntimeServices>
.所以,当你要求 IOptions<RuntimeServices>
,没有,您将获得一个具有所有默认值的新实例。
你想要:
保留
AddSingleton
并使用public ApplicationController(RuntimeServices services)
删除
AddSingleton
调用并使用services.Configure<RuntimeServices>(_configuration)
关于c# - 使用 IServiceCollection.AddSingleton() 的单个对象实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51768185/