Перемещение файлов конфигурации для DLL в приложение, которое вызывает DLL
У меня есть веб-приложение, в котором есть функция поиска. Алгоритм поиска скомпилирован в отдельную dll. В коде С# для алгоритма поиска я использую строки, хранящиеся в файле настроек, чтобы указать на каталог, в котором находится индекс поиска. После компиляции кода поиска информация о настройках включается в Search.dll.config
, который помещается в каталог bin вместе с Search.dll. Теперь в моем веб-приложении я добавляю Search.dll в ссылки. Файл конфигурации не добавляется в веб-приложение. Однако веб-приложение работает нормально и знает, где находится файл. Поскольку внутри Settings.Designer
он использует DefaultSettingValueAttribute
для назначения значения по умолчанию, если конфигурационный файл там отсутствует.
Как добавить Search.dll.config
в мое веб-приложение, чтобы оператор мог изменить местоположение файлов индекса на сервере, если это необходимо?
Спасибо
EDIT:
Я попытался добавить файл конфигурации в свою папку развертывания. Но ASP.NET помещает DLL в каталог в C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root...... и файл конфигурации не копируется там. Поэтому я не знаю, как включить конфигурационный файл с моим кодом.
Спасибо за вашу помощь.
Примечание:
Я использовал следующий код, чтобы получить значения конфигурационного файла в приложении. Тем не менее, это зависит от DLL и файла конфигурации, которые находятся в одной папке, и я не знаю, как это сделать.
var executingAssembly = System.Reflection.Assembly.GetExecutingAssembly();
var location = executingAssembly.Location; //C:\MyApp\bin\Debug\Search.dll
var config = ConfigurationManager.OpenExeConfiguration(location);
var sections = config.Sections; //count of this is 21
ConfigurationSectionGroup csg = config.GetSectionGroup("applicationSettings");
ConfigurationSectionCollection csc = csg.Sections;
ConfigurationSection cs = csc.Get("Search.Properties.Settings");
Ответы
Ответ 1
Лучше всего добавить конфигурацию в веб-проект напрямую..NET не поддерживает конфигурацию, связанную с библиотекой, в том виде, в котором вы пытаетесь; и это по дизайну. Другим пользователям вашей библиотеки может потребоваться другая конфигурация. Отметьте файл как содержимое, которое должно быть скопировано в выходную папку.
EDIT:
Для этого установите "Build Action" в "Content" и "Copy to Output Directory" как "Скопировать, если новый" в свойствах файла. Вы можете открыть файл в папке bin с помощью HttpRuntime.BinDirectory
. Возможно, вы захотите передать это местоположение в свою библиотеку, вместо того, чтобы библиотека предполагала, что она запущена в веб-проекте.
В качестве альтернативы просто вставьте нужную конфигурацию в web.config(в конфигурационных файлах есть возможность разбить настройки в отдельный файл).
Наконец, вы можете рассмотреть возможность вложения файла в качестве ресурса.
EDIT:
Посмотрев на код, который вы используете, просто переместите его в web.config. Гораздо проще и идиоматично. После этого в web.config просто используйте ConfigurationManager.GetSection()
, чтобы прочитать ваш раздел.
Кстати, есть бесплатный конструктор раздела конфигурации, который очень упрощает создание классов для поддержки настраиваемых конфигурационных разделов. Посмотрите в онлайн-галерею VS Extensions:
http://visualstudiogallery.msdn.microsoft.com/2a69f74e-83df-4eb0-8cac-cd83b451cd1d?SRC=VSIDE
Ответ 2
Идеальный способ - удалить зависимость конфигурации от DLL. DLL предназначена для использования приложением, а конфигурация принадлежит прикладной программе, а не dll.
В большинстве сценариев вы можете избавиться от зависимости/чтения от конфигурации в коде dll, используя инъекцию зависимостей либо через контейнер DI, либо с помощью ручной компоновки.
если ваша поисковая dll зависит от настроек, сделайте настройки зависимыми для вашего класса точки входа dll и продолжите с кодом dll, так как ваш класс точки входа получает его настройки.
Затем вы можете указать значение настроек из своего приложения, будь то web/windows/console и путем чтения из файла конфигурации/db/веб-службы/файловой системы.
пример кода:
В dll:
public interface ISearcherDirectorySettings
{
string[] SearchIndexPointers { get; }
}
public class Searcher
{
private readonly ISearcherDirectorySettings _searchDirctorySettings;
public Searcher(ISearcherDirectorySettings searchDirtorySettings)
{
_searchDirctorySettings = searchDirtorySettings;
}
public void SearchAlgorithm()
{
var indexes = _searchDirctorySettings.SearchIndexPointers;
// search code
}
}
В вашем приложении:
public class SearcherDirectorySettings : ISearcherDirectorySettings
{
private readonly string[] _pointers;
public SearcherDirectorySettings(string[] pointers)
{
_pointers = pointers;
}
public string[] SearchIndexPointers
{
get { return _pointers; }
}
}
public class ApplicationRootClass //Owns configuration file
{
const string FirstPointerKey = "File1";
const string SecondPointerKey = "File2";
private Func<string, string> _getFromConfig = key => ConfigurationManager.AppSettings[key];
public ApplicationRootClass()
{
var searcherDirectorySettings = new SearcherDirectorySettings(new[] { _getFromConfig(FirstPointerKey),_getFromConfig(SecondPointerKey) });
var searcher = new Searcher(searcherDirectorySettings);
searcher.SearchAlgorithm();
}
}
При этом вы можете добиться "быстрого сбоя". вы можете использовать поисковые DLL в любом приложении, и приложение несет ответственность за предоставление значений настроек.
Если вы в конечном итоге используете DLL в нескольких приложениях/проектах и дублируете код класса настроек, используйте компонент утилиты, который выполняет задание или перемещает класс настроек в dll, но оставляйте экземпляр класса настроек в приложении.
Ответ 3
Вот как вы делаете то, что хотите, в отличие от того, что, по мнению некоторых, вам следует делать:
(извините, я сейчас работаю в vb)
Скажем, что dll называется mycompany.mynamespace.dll
- Переименуйте файл app.config в проект dll в mycompany.mynamespace.dll.config
- В его свойствах скажем Копировать, если более новый
-
Используйте этот код (внутри dll) для доступа к вашим настройкам:
Dim appConfig = ConfigurationManager.OpenExeConfiguration(Me.GetType.Assembly.Location)
_WorkingDirectory = appConfig.AppSettings.Settings("WorkingDirectory").Value