ASP.NET Core 7中AppSettings迁移至依赖注入的方法及相关疑问
ASP.NET Core 7中AppSettings迁移至依赖注入的方法及相关疑问
嘿,我完全理解你从ASP.NET MVC 5转到ASP.NET Core 7时的困惑——毕竟配置读取和依赖注入(DI)的玩法确实有不小的变化,我来一步步给你捋清楚这些问题:
关于Core 7中读取配置的正确性
你在Program.cs里写的var myKey = builder.Configuration["MyKey"]这种读取配置的方式是正确的,不过Core 7更推荐用**强类型配置+IOptions
public class AppSettings { public string MyKey { get; set; } public string BucketName { get; set; } public string PublicKey { get; set; } // 其他配置项... }
然后在Program.cs里绑定:
builder.Services.Configure<AppSettings>(builder.Configuration);
之后在需要的地方注入IOptions<AppSettings>来获取配置:
private readonly AppSettings _settings; public SomeClass(IOptions<AppSettings> settings) { _settings = settings.Value; // 读取配置:_settings.MyKey }
自定义类如何获取服务和配置
你说得对,不能在业务类里直接访问WebApplication.CreateBuilder——这违反了DI的设计原则。正确的做法是通过构造函数注入依赖:
- 先在Program.cs里把你需要的服务注册到DI容器中(比如你的DbContext、AmazonS3Client、自定义服务等)
- 在自定义类的构造函数中声明需要的依赖,DI容器会自动把实例传递进来,不需要你手动创建
比如你原来的静态方法GetResources,就可以改成一个服务类的非静态方法,通过注入获取需要的DbContext、S3客户端和配置。
现有代码的改造思路
你不需要给每个类都强制加接口,但使用接口能让代码更易测试(比如Mock依赖)、更松耦合,是推荐的做法。我们来改造你给出的GetResources示例:
步骤1:注册依赖到DI容器(Program.cs)
// 1. 绑定强类型S3配置 builder.Services.Configure<S3Settings>(builder.Configuration.GetSection("S3Settings")); // 2. 注册DbContext(假设你的SqlEntities已经升级为Core的DbContext) builder.Services.AddDbContext<SqlEntities>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); // 3. 注册AmazonS3Client为单例服务 builder.Services.AddSingleton<IAmazonS3>(sp => { var s3Settings = sp.GetRequiredService<IOptions<S3Settings>>().Value; return new AmazonS3Client(s3Settings.PublicKey, s3Settings.PrivateKey, RegionEndpoint.USEast); }); // 4. 注册你的资源服务 builder.Services.AddScoped<IResourceService, ResourceService>();
步骤2:创建强类型配置类
public class S3Settings { public string BucketName { get; set; } public string PublicKey { get; set; } public string PrivateKey { get; set; } }
步骤3:改造资源服务类
// 可选但推荐的接口 public interface IResourceService { void GetResources(SheetModel sheet); } public class ResourceService : IResourceService { private readonly SqlEntities _dbContext; private readonly IAmazonS3 _s3Client; private readonly S3Settings _s3Settings; // 构造函数注入所有需要的依赖 public ResourceService( SqlEntities dbContext, IAmazonS3 s3Client, IOptions<S3Settings> s3Settings) { _dbContext = dbContext; _s3Client = s3Client; _s3Settings = s3Settings.Value; } public 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;"; var request = new GetPreSignedUrlRequest() { BucketName = _s3Settings.BucketName, Expires = DateTime.UtcNow.AddMinutes(30), }; // 后续逻辑和原来一致,只是用注入的_dbContext和_s3Client替代手动创建的实例 var row = _dbContext.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 = _s3Client.GetPreSignedURL(request); } else { Console.WriteLine(string.Format(FMT, "Data", "Sticker", "Data", sheet.DAMDLN)); } // 剩下的图片、花环逻辑同理替换... } }
步骤4:在需要使用的地方注入服务
比如在PageModel里:
public class IndexModel : PageModel { private readonly IResourceService _resourceService; public IndexModel(IResourceService resourceService) { _resourceService = resourceService; } public void OnGet() { var sheet = new SheetModel(); // 根据实际场景获取SheetModel实例 _resourceService.GetResources(sheet); } }
能不能直接读取配置值?
可以,但不推荐:
- 如果你只是临时过渡,可以注入
IConfiguration直接读取,比如:public SomeClass(IConfiguration configuration) { var bucketName = configuration["BucketName"]; } - 甚至你可以安装
Microsoft.Extensions.Configuration.ConfigurationManager包,继续使用ConfigurationManager.AppSettings["SomeKey"],但这种方式不符合Core的DI设计理念,会让代码耦合度高,难以测试和维护,只建议在旧代码迁移时临时使用,新代码还是尽量用DI+强类型配置的方式。
备注:内容来源于stack exchange,提问作者user22019322
相关产品推荐
相关产品推荐

