英文:
How to transfer AppSettings to use ASP.NET Core 7's dependency injection?
问题
In ASP.NET Core 7, the approach to reading configuration settings has indeed shifted away from ConfigurationManager.AppSettings
to use the built-in dependency injection and configuration system. You can still access configuration values directly, but the way to do it has changed. Here's how you can access configuration values in ASP.NET Core 7:
- Startup Configuration: In your application's
Startup.cs
file, you can configure your application's settings usingappsettings.json
or other configuration sources. You typically do this in theConfigureServices
method.
public void ConfigureServices(IServiceCollection services)
{
// Add configuration to the services collection
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
services.AddSingleton(configuration);
}
- Accessing Configuration in Services: Now, you can access configuration values in your services by injecting
IConfiguration
into your classes or methods.
public class MyService
{
private readonly IConfiguration _configuration;
public MyService(IConfiguration configuration)
{
_configuration = configuration;
}
public void SomeMethod()
{
// Access a configuration value
var myValue = _configuration["MyKey"];
}
}
- appsettings.json: In your
appsettings.json
file, you can define your configuration settings like this:
{
"MyKey": "MyValue"
}
This approach offers more flexibility and better integration with ASP.NET Core's dependency injection system. It also allows you to manage configuration values for different environments more easily using JSON files like appsettings.Development.json
, appsettings.Production.json
, etc.
Regarding your question about whether every class needs to be changed to work with an interface for clients like this, it's not necessary to change every class. You typically use interfaces when you want to implement dependency injection for certain services or components. You can gradually update your code to utilize dependency injection as needed, especially for services where you find it beneficial.
So, to summarize, in ASP.NET Core 7, you can still access configuration values directly, but it's recommended to embrace the built-in configuration and dependency injection system for better maintainability and testability of your application.
英文:
I'm trying to understand how to use the code we have in ASP.NET MVC 5 with the newer ASP.NET Core 7.
From what I can tell, Core 7 no longer uses the AppSettings approach. Instead, Microsoft wants developers to use dependency injection. This is the article I am trying to follow:
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-7.0
I see where objects are declared and used in the file Program.cs:
using DIsample2.Services;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddScoped<Service1>();
builder.Services.AddSingleton<Service2>();
var myKey = builder.Configuration["MyKey"];
builder.Services.AddSingleton<IService3>(sp => new Service3(myKey));
var app = builder.Build();
And then the class is built differently to include the interface:
public class IndexModel : PageModel
{
private readonly Service1 _service1;
private readonly Service2 _service2;
private readonly IService3 _service3;
public IndexModel(Service1 service1, Service2 service2, IService3 service3)
{
_service1 = service1;
_service2 = service2;
_service3 = service3;
}
public void OnGet()
{
_service1.Write("IndexModel.OnGet");
_service2.Write("IndexModel.OnGet");
_service3.Write("IndexModel.OnGet");
}
}
In Core 7, is this the correct way to read from a configuration file like AppSettings?
In the code above, the instantiation of PageModel is handled by the Visual Studio 2022 IDE. If I were to attempt to create a class that used services like that, I would need instances of the services to pass in. Where do I get those? It looks like Microsoft gets the services and configuration settings from var builder = WebApplication.CreateBuilder(args)
, but that is not something I should be accessing from classes in our code.
Here is a sample piece of code from what we have now:
public static void GetResources(SheetModel sheet)
{
const string FMT = "No {0} File For SQL: SELECT FilePath FROM ResourceManager WHERE Category1='{1}' AND Category2='{2}' AND Category3='{3}' AND IsActive=1;";
using (var db = new SqlEntities())
{
var request = new GetPreSignedUrlRequest()
{
BucketName = $"{ConfigurationManager.AppSettings["BucketName"]}",
Expires = DateTime.UtcNow.AddMinutes(30),
};
var client = new AmazonS3Client(
$"{ConfigurationManager.AppSettings["PublicKey"]}",
$"{ConfigurationManager.AppSettings["PrivateKey"]}",
RegionEndpoint.USEast);
var row = db.AssetManagers.FirstOrDefault(m =>
m.Category1 == "Sticker" &&
m.Category2 == "Data" &&
m.Category3 == sheet.DAMDLN &&
m.IsActive);
if (row != null)
{
request.Key = $"{row.FilePath}".Trim();
sheet.Href = client.GetPreSignedURL(request);
} else
{
Console.WriteLine(String.Format(FMT, "Data", "Sticker", "Data", sheet.DAMDLN));
}
row = db.AssetManagers.FirstOrDefault(m =>
m.Category1 == "Sticker" &&
m.Category2 == "Image" &&
m.Category3 == sheet.DADLRN &&
m.IsActive);
if (row != null)
{
request.Key = $"{row.FilePath}".Trim();
sheet.Image = client.GetPreSignedURL(request);
}
else
{
Console.WriteLine(String.Format(FMT, "Image", "Window Sticker", "Image", sheet.DADLRN));
}
row = db.AssetManagers.FirstOrDefault(m =>
m.Category1 == "Sticker" &&
m.Category2 == "Image" &&
m.Category3 == "c_wreath" &&
m.IsActive);
if (row != null)
{
request.Key = $"{row.FilePath}".Trim();
sheet.Wreath = client.GetPreSignedURL(request);
}
else
{
Console.WriteLine(String.Format(FMT, "Wreath", "Sticker", "Image", "c_wreath"));
}
request.Key = (row != null) ? $"{row.FilePath}".Trim() : string.Empty;
sheet.Wreath = client.GetPreSignedURL(request);
}
}
Would every class need to be changed to work with an interface for clients like this?
Reading from ConfigurationManager.AppSettings["SomeKey"]
seemed simpler and more direct.
Can I still get to values directly, or has that door been closed?
答案1
得分: 1
使用以下代码示例:
using (var db = new SqlEntities())
现代 ASP.NET Core 高度依赖于依赖注入,我强烈建议遵循这种模式,以便您不必在实现中进行实例化或读取配置。
快速而不太规范的方法是将您的静态方法移到某个服务中,将 IConfiguration
注入其中,用注入配置的调用替代 ConfigurationManager.AppSettings
。例如:
appsettings.json
{
// ....,
"AmazonS3Client":{
"PublicKey": "...",
"PrivateKey": "..."
}
}
然后在服务中:
public class MyService // 可以考虑使用接口
{
// 需要引用 Microsoft.Extensions.Configuration;
private readonly IConfiguration Configuration;
public MyService (IConfiguration configuration)
{
Configuration = configuration;
}
public ... GetResources(...)
{
var publicKey = Configuration["AmazonS3Client:PublicKey"];
var privateKey = Configuration["AmazonS3Client:PublicKey"];
// ...
}
}
请注意,更常见的方法是为设置创建一个专门的类,并将其注册到依赖注入容器中,并通过 Options 模式 解析配置。
了解更多信息:
-
ASP.NET Core 中的配置 - 文档广泛涵盖了此主题,包括用于在开发环境中存储密钥的特殊配置提供程序。
-
.NET 6 (稳定版) 中的 Program.cs 中的 IConfiguration 设置 - 如果当前情况下重构工作量太大,而您希望使用静态配置方法(尽管我不建议这样做)。
英文:
using (var db = new SqlEntities())
- modern ASP.NET Core heavily relies on dependency injection and I highly recommend to follow this pattern, so you try not to new up or read configuration in the implementation.
The +/- quick-n-dirty approach would be to move your static method into some service, inject IConfiguration
into it substituting ConfigurationManager.AppSettings
with call to the injected config. For example:
appsettings.json
{
// ....,
"AmazonS3Client":{
"PublicKey": "...",
"PrivateKey": "..."
}
}
And then in the service:
public class MyService // maybe an interface here
{
// requires using Microsoft.Extensions.Configuration;
private readonly IConfiguration Configuration;
public MyService (IConfiguration configuration)
{
Configuration = configuration;
}
public ... GetResources(...)
{
var publicKey = Configuration["AmazonS3Client:PublicKey"];
var privateKey = Configuration["AmazonS3Client:PublicKey"];
// ...
}
}
Note that more common approach is to create a special class for settings and register it the DI and resolve the config, for example via Options pattern.
Read more:
-
Configuration in ASP.NET Core - docs extensively cover the topic, including special configuration provider for storing secrets in the development environment.
-
.NET 6 (stable) IConfiguration setup in Program.cs - if refactoring is too big of a job at the moment and you want static configuration approach (I would not recommend it though)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论