Если приложение ASP.NET использует много библиотек DLL, каков наилучший подход для разделения конфигураций каждой библиотеки DLL? - PullRequest
3 голосов
/ 31 октября 2010

После создания настроек для каждого dll создается файл .dll.config. Если это dll будет частью приложения asp.net, как сохранить эти конфигурации отдельно для каждого dll и не объединять их в web.config?

Пример: У меня есть библиотека классов (DLL) GMailSender, которая отправляет электронную почту через серверы GMail. Все, что вам нужно, это экземпляр GMailSender, например:

GMailSender gms = new GMailSender();
gms.To = "myfriend@yahoo.com";
gms.Subject = "System.Configuration dilemma";
gms.Body = "Can anyone help me with this question ?";
gms.Send();

Предположим, что GMailSender находится внутри GMailSender.dll, а его файл конфигурации - GMailSender.dll.config, а имя пользователя и пароль учетной записи GMail находятся внутри него.

Я хочу, чтобы DLL использовал сам файл конфигурации (как dll, так и config в одной и той же директории, т.е. в папке Bin приложения ASP.NET) или рядом с настольным приложением. Таким образом, GMailSender не зависит от того, кто использует его для получения своих конфигураций (текущий AppDomain, кто загрузил этот DLL).

Я хочу это без реконструкции колеса (нет пользовательских классов конфигурации). Я предполагаю, что это возможно с System.Configuration, но это пространство имен, вероятно, худшее из .NET!

Пожалуйста, не говорите, почему вы разработали так, чтобы ...

Это проект, основанный на plug-in, и, наконец, MEF сделайте что-то вроде этого сейчас в .NET 4.0, но есть такая же проблема для Parts конфигураций. С MEF по крайней мере мне больше не нужно спорить о plugin-based преимуществах дизайна.

Ответы [ 5 ]

4 голосов
/ 09 декабря 2010

То, что вам нужно, может быть достигнуто с помощью Разделы пользовательской конфигурации .Эта статья MSDN содержит некоторые подробности и примеры того, как реализовать такие разделы конфигурации.

Если вам нужны простые ключи / значения конфигурации, как в разделе appSettings, тогдасоздать пользовательский раздел конфигурации довольно просто.

Первое, что вам нужно сделать, это определить свой раздел конфигурации внутри web.config:

<configSections>
  <section name="GmailSettings" restartOnExternalChanges="true" type="System.Configuration.NameValueFileSectionHandler" />
</configSections>

Теперь внутриВ файле web.config вы можете объявить раздел GmailSettings и установить расположение внешнего файла конфигурации, который вы собираетесь использовать для этого параметра:

<GmailSettings configSource="GmailSettings.config"></GmailSettings>

configSource указывает имя и расположение внешнего файла конфигурации, используемого для определения раздела GmailSettings.Обратите внимание на атрибут restartOnExternalChanges, используемый при определении раздела.Установите значение true, если вы хотите, чтобы приложение автоматически перезапускалось при изменении файла GmailSettings.config (как это происходит при изменении файла web.config).

Ниже приведен пример реализации GmailSettings.config file:

<?xml version="1.0"?>
<GmailSettings>
  <add key="userName" value="blabla"/>
  <add key="password" value="moreBla"/>
</GmailSettings>

Вы можете получить доступ к настройкам из GmailSettings, используя метод ConfigurationManager.GetSection() или реализовав вспомогательный класс , как показано ниже:

public class GmailSettings
{
    private static readonly GmailSettings _instance = new GmailSettings();
    private NameValueCollection _settings = ConfigurationManager.GetSection("GmailSettings") as NameValueCollection;

    public static GmailSettings Instance
    {
        get { return _instance; }
    }

    public string this[string key]
    {
        get { return _settings[key]; }
    }
}

Доступ к настройкам теперь можно получить, например, GmailSettings.Instance["userName"].

Надеюсь, это поможет.

1 голос
/ 09 декабря 2010

То, что вы ищете, не может быть сделано из коробки. Кроме того, ASP.NET выполняет теневое копирование в DLL, поэтому написать собственный класс конфигурации непросто. Ваши DLL не запускаются из папки Bin. Они запускаются из appDomainSetup.CachePath, поэтому файлы * .dll.config не находятся рядом со своими сборками во время выполнения.

Вы можете добавить ссылку на файлы * .dll.config в файле web.config вместо копирования / вставки всех ключей / значений из файлов конфигурации DLL в файл web.config; Это возможно при использовании элемента File в web.config.

Я думаю, что это не было задумано дизайнерами в прошлом, а композиция стала популярной в последние годы.

1 голос
/ 03 декабря 2010

Чтобы сделать то, что, я полагаю, вы хотите сделать - дать вашей DLL файл конфигурации, о котором ссылочные сборки ничего не нужно, вы можете [1] сделать что-то вроде следующего кода.

static class DllConfigurationFactory
{
    public static Configuration GetConfigurationInstance()
    {
        string           callingAssemblyPath = Assembly.GetCallingAssembly().Location ;
        string           configFilePath      = string.Concat( callingAssemblyPath , ".config" ) ;

        // getAttributes hurls with a multitude of exceptions
        FileAttributes   attributes  = File.GetAttributes( configFilePath ) ;
        bool             isDirectory = ( (attributes&FileAttributes.Directory) == FileAttributes.Directory ? true : false ) ;
        if ( isDirectory )
        {
            throw new FileNotFoundException() ;
        }

        // check for (and die with an SecurityException) if we dont' have read access
        new FileIOPermission( FileIOPermissionAccess.Read , configFilePath ).Demand() ;

        ExeConfigurationFileMap configMap = new ExeConfigurationFileMap();
        configMap.ExeConfigFilename = configFilePath ;
        Configuration instance = ConfigurationManager.OpenMappedExeConfiguration(configMap, ConfigurationUserLevel.None);
        return instance ;
    }

}

Этот фабричный метод выполняет следующие действия:

  1. Находит полный путь к сборке вызывающей стороны ((а не к сборке, содержащей фабрику - в конце концов, она может быть в своей собственной DLL).

  2. Добавляет ".config" в конец этого пути (таким образом, получая что-то вроде 'C: \ usr / bin / local / foo / myAssembly.dll.config'.

  3. Гарантирует, что этот файл существует и доступен для чтения, и, если нет, выдает соответствующее исключение.

  4. Использование этого пути в качестве источника создает новый экземпляр System.Configuration.Configuration и возвращает его вызывающей стороне.

Примечания

  • Visual Studio возьмет app.config в ваш проект DLL и превратит его в файл foo.dll.config, , но ваша система build / deploy / install отвечает за копирование его в правильное местоположение (ы). Visual Studio поместит его в каталог bin для проекта DLL, но дальше копировать не будет.
  • Возможно, вам придется поэкспериментировать - вам может понадобиться включить соответствующие элементы в элемент, даже для «стандартных» разделов, поскольку вы находитесь за пределами обычной иерархии конфигурационного файла. Я не уверен в этом, хотя. В моем тесте он нашел и загрузил элемент без определенного элемента, поэтому у вас может быть полный доступ к файлам конфигурации пользователя и машины, но я не даю никаких гарантий по этому поводу. YMMV и все такое.

Удачи!

[1] TMTOWTDI, как говорят в Perl (есть несколько способов сделать это). Вы также можете, например, создать пользовательский раздел и оставить его в machine.config.

И для этого не требуется использовать систему конфигурации .Net: ваш фабричный метод может влить в любой произвольный XML и десериализовать его в объект по вашему выбору. Это даст вам строго типизированный, связанный доступ к свойствам конфигурации, хотя и за счет автоматического обновления при изменении файла конфигурации. Хотя ... вы могли бы просто поместить оболочку вокруг стандартного объекта Configuration, который бы обеспечивал то же самое.

1 голос
/ 31 октября 2010

Создание App.config для DLL не является хорошей практикой. Конфигурация принадлежит запущенному приложению. Предполагается, что библиотека классов dll предназначена только для предоставления услуг вызывающему приложению.

ОДНАКО

Если вы написали библиотеки DLL самостоятельно, вы можете сделать так, чтобы код этих библиотек DLL предпочитал собственный независимый файл .dll.config, а не глобальный App.config / Web.config (в вашем случае ASP.NET), используя хитрость .

Этот метод позволяет открыть файл .config любого исполняемого файла, но никто не запрещает вам вызывать его с «Mydll.dll» в качестве аргумента, и имеет тот же эффект. Но это работает, только если вы можете получить доступ к коду этих DLL.

Хорошей практикой является использование разделов конфигурации, которые легко поддерживать при объединении в одном файле конфигурации.

0 голосов
/ 09 декабря 2010

Я бы добавил параметры конфигурации в файл web.config и позвонил бы:

ConfigurationManager.AppSettings [ "DllName.MySetting"]

Это означает, что все параметры конфигурации находятся в одном месте, а не в папке Bin.

...