【问题标题】:Keeping configuration data external from Class Libraries将配置数据保存在类库外部
【发布时间】:2011-10-12 04:46:50
【问题描述】:

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

// 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>

然后我会使用工厂通过反射创建数据上下文

public static DataContext GetContext()
{
    string assembly = ConfigurationManager.AppSettings("DAL-Assembly");
    string type = ConfigurationManager.AppSettings("DAL-Type");

    Assembly a = Assembly.Load(assembly);
    return (DataContext)a.CreateInstance(type);
}

问题是现在我明白类库必须使用调用应用程序的配置文件。这意味着它将在演示文稿中查找 app.config 或 web.config - 这似乎不正确。

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

【问题讨论】:

  • 抱歉,从第一天起 .NET 就是这样做的。这也是有道理的,因为配置是使用 应用程序。不要将其视为“表示层”。网站应用程序。

标签: c# asp.net appsettings


【解决方案1】:

我会尝试将配置分开并实际将其注入相关层。因此,在您的 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 的具体类,并使用配置文件中的值设置其成员并传递上课。有关我提出的与此相关的问题,请参阅此链接:Best way of injecting application configuration

这就是你要找的东西吗?

【讨论】:

    【解决方案2】:

    我总是为从 .config 文件中读取的所有值创建一个具有静态只读属性的 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;
            }
        }
    }
    

    我总是为依赖于设置的项目保留一个类似的 Config 类。在您的场景中,DAL 和服务层可能每个都有这样的类。我还进行基本形式的验证,即检查缺失值并抛出适当的异常,以便应用尽快失败,或者只返回一个合理的默认值。

    注意为你的配置值命名唯一,如果我知道该库将在其他场景中使用,我通常会在它们前面加上项目名称。

    【讨论】:

    • 虽然不是一个坏方法,但您也将您的应用程序/层与具体的配置风格联系起来。如果你说想要使用数据库来获取你的配置会发生什么?现在您必须更改所有配置类,因为它们默认使用配置管理器。如果一切都隐藏在接口后面,那么只有获得配置的顶层必须更改,如果您使用 IoC 策略,这非常简单。
    • 我应该在哪里放置 Config 类?在 DataLayer 项目中,在业务项目中......?
    • @emert117 每个项目可以/应该有一个 Config 类来访问它定义的设置。
    猜你喜欢
    • 2016-09-29
    • 2016-07-04
    • 1970-01-01
    • 1970-01-01
    • 2012-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-11
    相关资源
    最近更新 更多