将配置数据保存在类库外部

发布于 2024-12-09 06:08:20 字数 939 浏览 2 评论 0原文

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

// 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 层外部的最佳方法是什么?

Say I have an application with the following structure.

// ASP.NET MVC (Web Project)
// Service/Business Layer (Class Library)
// DAL (Class Library)

Initially I wanted to use an App.config file in the DAL class library which would hold app settings like this:

<appSettings>
   <add key="DAL-Assembly" value="DAL.LinqToSql.DataContexts"/>
   <add key="DAL-Type" value="DAL.LinqToSql.DataContexts.MyDataContext" />
</appSettings>

And then I would use a factory to create the data context using reflection

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);
}

The problem is that now I understand that a Class Library has to use the configuration file of the calling application. Which means that it would be looking in the presentation for the app.config or web.config - which doesn't seem right.

In this DAL situation, what is the best way to keep the concrete DataContext specification contained in the DAL layer, without having to rebuild each time it is changed? Or even in a broader sense, the best way to keep configuration external in the DAL layer?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

懷念過去 2024-12-16 06:08:20

我会尝试将配置分开,并将其实际注入到相关层中。因此,在您的 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 的具体类,并使用配置文件中的值设置其成员并传递该类大约。有关我提出的与此相关的问题,请参阅此链接:注入应用程序配置的最佳方式< /a>

这是您正在寻找的东西吗?

I would try and keep the configuration separate and actually inject it into the layer in question. So in your DAL layer I would perhaps have a factory class that dealt out the particular data gateways and this factory would take an IDataAccessConfiguration parameter in its default constructor. Then you could set static properties in a local configuration class or pass a local copy of the interface into a context when creating it. Example :

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);  
    }
}

Then, when you actually want to get the settings from the particular app.config file you can do it in the standard manner, create a concrete class that implements IDataAccessConfiguration and set its members with the values from the config file and pass that class around. See this link for a question I asked that relates to this : Best way of injecting application configuration

Is this the sort of thing you are looking for?

潇烟暮雨 2024-12-16 06:08:20

我总是为从 .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 和服务层可能都会有这样一个类。我还进行基本形式的验证,即检查缺失值并抛出适当的异常,以便应用程序尽快失败,或者只是返回一个合理的默认值。

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

I always create a Config class with static readonly properties for all the values read from .config files. It's tremendously helpful, as it gives you easy access to the strongly types values and it doesn't really if the value is set in a web.config for your website, or in a app.config for your test projects.

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

    public static string SearchLogConnectionString
    {
        get
        {
            return ConfigurationManager.ConnectionStrings["SearchLog"].ConnectionString;
        }
    }
}

I always keep a Config class like that with the project that depends on the settings. In your scenario, the DAL and Service layer will probably each have such a class. I also do basic forms of validation, i.e. check for missing values and throw appropiate exceptions so the app fails as fast as possible, or just return a sensible default value.

Be careful to name your configuration values uniquely, I usually prefix them with the project name, if I know the library is going to be used in other scenarios.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文