Перемещение файлов конфигурации для 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