C# 从类库外部保留配置数据

C# 从类库外部保留配置数据,c#,asp.net,appsettings,C#,Asp.net,Appsettings,假设我有一个具有以下结构的应用程序 // ASP.NET MVC (Web Project) // Service/Business Layer (Class Library) // DAL (Class Library) 最初,我想在DAL类库中使用App.config文件,该文件将保存如下应用程序设置: <appSettings> <add key="DAL-Assembly" value="DAL.LinqToSql.DataContexts"/> &

假设我有一个具有以下结构的应用程序

// ASP.NET MVC (Web Project)
// Service/Business Layer (Class Library)
// DAL (Class Library)
最初,我想在DAL类库中使用App.config文件,该文件将保存如下应用程序设置:

<appSettings>
   <add key="DAL-Assembly" value="DAL.LinqToSql.DataContexts"/>
   <add key="DAL-Type" value="DAL.LinqToSql.DataContexts.MyDataContext" />
</appSettings>
问题是,现在我知道类库必须使用调用应用程序的配置文件。这意味着它将在演示文稿中查找app.config或web.config-这似乎不正确


在这种DAL情况下,保持DAL层中包含的具体DataContext规范的最佳方法是什么,而不必在每次更改时重新构建它?甚至从更广泛的意义上讲,在DAL层中保持外部配置的最佳方法是什么?

我总是为从.Config文件读取的所有值创建一个具有静态只读属性的配置类。这非常有帮助,因为它使您可以轻松访问强类型值,而实际上,如果在网站的web.config或测试项目的app.config中设置了该值,则不需要这样做

public class Config
{
    public static string QueriesPath
    {
        get
        {
            return ConfigurationManager.AppSettings["QueriesPath"].ToString();
        }
    }

    public static string SearchLogConnectionString
    {
        get
        {
            return ConfigurationManager.ConnectionStrings["SearchLog"].ConnectionString;
        }
    }
}
我总是在依赖于设置的项目中保留这样的配置类。在您的场景中,DAL和服务层可能都有这样一个类。我还进行基本形式的验证,即检查缺少的值并抛出适当的异常,以便应用程序尽快失败,或者只是返回一个合理的默认值


如果我知道库将在其他场景中使用,请小心唯一地命名您的配置值,我通常会在它们前面加上项目名称

我会尝试将配置分开,并将其实际注入到相关层中。因此,在DAL层中,我可能会有一个处理特定数据网关的工厂类,该工厂将在其默认构造函数中使用IDataAccessConfiguration参数。然后,您可以在本地配置类中设置静态属性,或者在创建接口时将接口的本地副本传递到上下文中。例如:

public interface IDataAccessConfiguration
{
    string Assembly { get; }
    string Type { get; }
}

public sealed class DataAccessfactory
{
    private IDataAccessConfiguration Config { get; set; }

    public DataAccessfactory(IDataAccessConfiguration config)
    {
        this.Config = config;
    }

    public ISomeDataContext GetSomeDataContext()
    {
        return new SomeDataContext(this.Config);
    }
}

public class SomeDataContext : ISomeDataContext
{
    private IDataAccessConfiguration Config { get; set;}

    public SomeDataContext(IDataAccessConfiguration config)
    {
        this.Config = config;
    }

    private DataContext GetDataContext()
    {
        Assembly a = Assembly.Load(this.Config.Assembly);       
        return (DataContext)a.CreateInstance(this.Config.Type);  
    }
}
然后,当您确实想要从特定的app.config文件中获取设置时,您可以使用标准方式,创建一个实现IDataAccessConfiguration的具体类,并使用配置文件中的值设置其成员,然后传递该类。我问了一个与此相关的问题,请参见此链接:


这就是您要找的东西吗?

对不起,从第一天开始.NET就是这样做的。这也是有意义的,因为配置是与应用程序一起进行的。不要将其视为“表示层”。网站就是应用程序。虽然这不是一个坏方法,但您也将应用程序/层绑定到具体的配置样式。如果要使用数据库获取配置,会发生什么?现在您必须更改所有配置类,因为它们默认使用Configuration Manager。如果所有东西都隐藏在一个接口后面,那么只有获取配置的顶层需要更改,如果您使用的是IoC策略,这是非常直接的?在数据层项目,在业务项目@emert117每个项目都可以/应该有一个配置类来访问它定义的设置。
public interface IDataAccessConfiguration
{
    string Assembly { get; }
    string Type { get; }
}

public sealed class DataAccessfactory
{
    private IDataAccessConfiguration Config { get; set; }

    public DataAccessfactory(IDataAccessConfiguration config)
    {
        this.Config = config;
    }

    public ISomeDataContext GetSomeDataContext()
    {
        return new SomeDataContext(this.Config);
    }
}

public class SomeDataContext : ISomeDataContext
{
    private IDataAccessConfiguration Config { get; set;}

    public SomeDataContext(IDataAccessConfiguration config)
    {
        this.Config = config;
    }

    private DataContext GetDataContext()
    {
        Assembly a = Assembly.Load(this.Config.Assembly);       
        return (DataContext)a.CreateInstance(this.Config.Type);  
    }
}