Хранение данных конфигурации вне библиотек классов - PullRequest
2 голосов
/ 12 октября 2011

Скажем, у меня есть приложение со следующей структурой.

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

Изначально я хотел использовать файл App.config в библиотеке классов DAL, в котором бы содержались такие настройки приложения:

<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, каков наилучший способ сохранить конкретную спецификацию DataContext, содержащуюся в слое DAL, без необходимости перестраивать каждый раз, когда она изменяется? Или даже в более широком смысле, лучший способ сохранить конфигурацию внешней на уровне DAL?

Ответы [ 2 ]

3 голосов
/ 12 октября 2011

Я бы попытался сохранить конфигурацию отдельно и фактически внедрить ее в рассматриваемый слой. Так что на вашем уровне 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, и установить его члены со значениями из файла конфигурации и передать класс вокруг. См. Эту ссылку для вопроса, который я задал, который относится к этому: Лучший способ внедрения конфигурации приложения

Это то, что вы ищете?

0 голосов
/ 12 октября 2011

Я всегда создаю класс 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 и Service, вероятно, будет иметь каждый класс. Я также делаю базовые формы проверки, то есть проверяю пропущенные значения и выкидываю подходящие исключения, чтобы приложение как можно быстрее завершалось сбоем, или просто возвращаю разумное значение по умолчанию.

Будьте осторожны, чтобы называть ваши значения конфигурации уникально, я обычно ставлю перед ними префикс с именем проекта, если знаю, что библиотека будет использоваться в других сценариях.

...