如何根据应用程序设置使用不同的模块?
How can I use different modules based on application settings?
我是 asp.net 核心的新手,我想在 asp.net 核心网络 API 启动期间设置 属性 值。
数据是从数据库中获取的,我需要整个应用程序的值,它应该只被调用一次。
我的项目中有两种状态,假设它是 A 和 B。在 A 中显示了一组项目,在 B 中显示了不同的项目。我从数据库中获取应用程序设置数据,并根据该数据在整个应用程序生命周期中显示 A 模块或 B 模块。
此问题的一般解决方案是配置一个要在 ServiceCollection 中注册的单例对象。
services.AddSingleton<ISingletonObject, SingletonObject>();
此类对象的构造函数将加载必要的数据,然后使用构造函数注入将单例对象加载到每个 class(例如控制器)。
public class SomeController(ISingletonObject singletonObject)
{
// singleton object will be injected with it's pre-loaded data available
}
对象 SingletonObject 的构造函数将只执行一次,无论它被服务集合注入了多少其他构造函数。
.NET 中没有全局变量,更不用说 C# 了。将配置数据存储在全局静态属性中不是一个好主意,因为它将您的代码与保存这些属性的静态 class 联系在一起,使编写或测试代码变得更加困难。
配置中间件
ASP.NET Core 通过配置中间件解决了这个问题,它可以从多个提供程序读取配置设置,包括文件、数据库甚至 in-memory 集合。 Configuration overview article 展示了如何使用字典作为配置源:
var builder = WebApplication.CreateBuilder(args);
var Dict = new Dictionary<string, string>
{
{"MyKey", "Dictionary MyKey Value"},
{"Position:Title", "Dictionary_Title"},
{"Position:Name", "Dictionary_Name" },
{"Logging:LogLevel:Default", "Warning"}
};
builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
config.Sources.Clear();
config.AddInMemoryCollection(Dict);
config.AddEnvironmentVariables();
if (args != null)
{
config.AddCommandLine(args);
}
});
builder.Services.AddRazorPages();
var app = builder.Build();
之后,所有 classes 都可以通过 IConfiguration
接口检索配置值,无论它们来自何处:
public class TestModel : PageModel
{
// requires using Microsoft.Extensions.Configuration;
private readonly IConfiguration Configuration;
public TestModel(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var myKeyValue = Configuration["MyKey"];
var title = Configuration["Position:Title"];
var name = Configuration["Position:Name"];
var defaultLogLevel = Configuration["Logging:LogLevel:Default"];
return Content($"MyKey value: {myKeyValue} \n" +
$"Title: {title} \n" +
$"Name: {name} \n" +
$"Default Log Level: {defaultLogLevel}");
}
}
在您的情况下,您可以从数据库加载设置并将它们注册为 Program.cs
中的 in-memory 源:
var Dict=LoadDataAsDictionary();
...
config.AddInMemoryCollection(Dict);
...
依赖注入中间件
另一种选择是将数据加载为强类型对象,并使用依赖注入中间件将其注册为 Signleton 实例:
var builder = WebApplication.CreateBuilder(args);
MyCacheData cacheData=LoadStronglyTypedData();
builder.Services.AddSingleton(cachedata);
这个 class 可以像其他 DI 服务或 IConfiguration
一样注入到页面和控制器中:
public class TestModel : PageModel
{
private readonly MyCacheData Data;
public TestModel(MyCacheData data)
{
Data = data;
}
我是 asp.net 核心的新手,我想在 asp.net 核心网络 API 启动期间设置 属性 值。 数据是从数据库中获取的,我需要整个应用程序的值,它应该只被调用一次。
我的项目中有两种状态,假设它是 A 和 B。在 A 中显示了一组项目,在 B 中显示了不同的项目。我从数据库中获取应用程序设置数据,并根据该数据在整个应用程序生命周期中显示 A 模块或 B 模块。
此问题的一般解决方案是配置一个要在 ServiceCollection 中注册的单例对象。
services.AddSingleton<ISingletonObject, SingletonObject>();
此类对象的构造函数将加载必要的数据,然后使用构造函数注入将单例对象加载到每个 class(例如控制器)。
public class SomeController(ISingletonObject singletonObject)
{
// singleton object will be injected with it's pre-loaded data available
}
对象 SingletonObject 的构造函数将只执行一次,无论它被服务集合注入了多少其他构造函数。
.NET 中没有全局变量,更不用说 C# 了。将配置数据存储在全局静态属性中不是一个好主意,因为它将您的代码与保存这些属性的静态 class 联系在一起,使编写或测试代码变得更加困难。
配置中间件
ASP.NET Core 通过配置中间件解决了这个问题,它可以从多个提供程序读取配置设置,包括文件、数据库甚至 in-memory 集合。 Configuration overview article 展示了如何使用字典作为配置源:
var builder = WebApplication.CreateBuilder(args);
var Dict = new Dictionary<string, string>
{
{"MyKey", "Dictionary MyKey Value"},
{"Position:Title", "Dictionary_Title"},
{"Position:Name", "Dictionary_Name" },
{"Logging:LogLevel:Default", "Warning"}
};
builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
config.Sources.Clear();
config.AddInMemoryCollection(Dict);
config.AddEnvironmentVariables();
if (args != null)
{
config.AddCommandLine(args);
}
});
builder.Services.AddRazorPages();
var app = builder.Build();
之后,所有 classes 都可以通过 IConfiguration
接口检索配置值,无论它们来自何处:
public class TestModel : PageModel
{
// requires using Microsoft.Extensions.Configuration;
private readonly IConfiguration Configuration;
public TestModel(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var myKeyValue = Configuration["MyKey"];
var title = Configuration["Position:Title"];
var name = Configuration["Position:Name"];
var defaultLogLevel = Configuration["Logging:LogLevel:Default"];
return Content($"MyKey value: {myKeyValue} \n" +
$"Title: {title} \n" +
$"Name: {name} \n" +
$"Default Log Level: {defaultLogLevel}");
}
}
在您的情况下,您可以从数据库加载设置并将它们注册为 Program.cs
中的 in-memory 源:
var Dict=LoadDataAsDictionary();
...
config.AddInMemoryCollection(Dict);
...
依赖注入中间件
另一种选择是将数据加载为强类型对象,并使用依赖注入中间件将其注册为 Signleton 实例:
var builder = WebApplication.CreateBuilder(args);
MyCacheData cacheData=LoadStronglyTypedData();
builder.Services.AddSingleton(cachedata);
这个 class 可以像其他 DI 服务或 IConfiguration
一样注入到页面和控制器中:
public class TestModel : PageModel
{
private readonly MyCacheData Data;
public TestModel(MyCacheData data)
{
Data = data;
}