C# ASP.Net 5配置及与类库的向后兼容性问题

3

我有多个旧版库,这些库通过ConfigurationManager进行自我配置。例如:

var port = ConfigurationManager.AppSettings["service.port"];

新的ASP.Net系统偏向于基于附加的“config.json”文件的强类型模型。示例(摘自Rick Strahl的Web日志):
//from AppSettings.cs
public class AppSettings
{
    public string SiteTitle { get; set; }
}

//from config.json
{
    "AppSettings": {
        "SiteTitle": "WebApplication2",
    },
    "Data": {
        "DefaultConnection": {
            "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=blahfoo;Trusted_Connection=True;MultipleActiveResultSets=true"
        }
    }
}

// from Startup.cs
public class Startup
{
    public IConfiguration Configuration { get; set; }

    public Startup(IHostingEnvironment env)
    {
        // Setup configuration sources.
        var configuration = new Configuration()
            .AddJsonFile("config.json")
            .AddJsonFile($"config.{env.EnvironmentName}.json", optional: true);

        configuration.AddEnvironmentVariables();
        Configuration = configuration;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        // Add Application settings to the services container.
        services.Configure<AppSettings>(Configuration.GetSubKey("AppSettings"));

        …
    }
}

我的问题是:在保持与其他应用程序库的向后兼容性的同时,是否有一种方法可以采用新的ASP.Net 5及其强类型配置方法?或者说,我能否利用我们组合中的常见库而无需重写它们?

我明白。问题在于我们有很多表面积和大量的遗留代码。虽然我完全同意所有遗留库都应该进行彻底改进,但目前这并不可行。我需要的是一个妥协方案,可以让我推进新技术(需要配置类)而不必维护多个相同库的副本或重写整个系统。 - Will Bellman
请查看 Configuration Section Designer 工具,它能让您轻松设计配置节和元素,并生成所需的样板代码(因为它有很多)。尽管新模型更简单,但将旧系统中的类转换成新的 DTOs 还需要一些工作。如果结构匹配,也许 AutoMapper 能帮上忙。 - Panagiotis Kanavos
听起来你需要在旧系统中使用类,这样你就不必重写旧代码。这可能更容易,配置系统是可插拔的。例如,您可以设计一个新的配置提供程序,从数据库或Json文件中读取。至少有一个示例使用数据库。 - Panagiotis Kanavos
再次……仍在对传统系统进行基本更改。……仍在重写旧库的重要部分。如果必须这样做,那么答案就是“不行,你必须重写大量的代码,并有可能破坏旧应用程序或维护多个相同库的副本。” - Will Bellman
通过新创建的 "AppSettings" 对象的属性反射,做类似这样的事情如何:ConfigurationManager.AppSettings[property.Name] = property.Value?这可能会奏效... - Will Bellman
显示剩余2条评论
1个回答

2
你的问题在于依赖具体实现的配置,使用ConfigurationManager类的静态成员而不是编写一个具有适当依赖注入的SOLID实现。
虽然你可以找到一些小技巧,使你无需更改代码即可使用新的配置模型,但我认为你应该利用这个机会重构你的代码并将当前配置抽象化到一个简单的接口中,如下所示: public interface IMyAppConfiguration { string Setting1 { get; } string Setting2 { get; } SomeOtherMoreComplexSetting Setting3 { get; } } 然后在需要其中一个设置的每个类中注入此依赖项,并提供一个实现,该实现包装当前的ConfigurationManager类和另一个实现,该实现包装新的配置模型。
这是SOLID设计重要性的完美例子,如果正确实施,则可以使代码维护和创新更加容易。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接