app.config для библиотеки классов

83

Я не вижу файл app.config, созданный для библиотеки классов мастером VS2008. В своем исследовании я обнаружил, что в приложении существует только один app.config.

Плохо ли добавлять app.config вручную в библиотеку классов или есть какие-либо другие методы, которые будут служить цели app.config в библиотеке классов?

Мне нужно сохранить информацию о конфигурации log4net в файле app.config.

Logeeks
источник
3
Вы можете прочитать исполняемый файл конфигурации проекта из своей библиотеки.
Акрам Шахда

Ответы:

102

Обычно не следует добавлять app.configфайл в проект библиотеки классов; он не будет использоваться без болезненного сгибания и скручивания с вашей стороны. Это совсем не повредит библиотечному проекту - просто ничего не сделает.

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

Эндрю Барбер
источник
23
Повезло тебе. Но я не отвечал на ваш вопрос. У вас явно есть какая-то самодельная система конфигурации, которая не относится к человеку, задающему здесь вопрос.
Эндрю Барбер
1
У меня есть библиотека классов Selenium WebDriver, которую я запускаю из NUnit для всех моих тестовых случаев. Я бы предпочел не беспокоиться о настройке конфигурации в NUnit. Как я могу сгибать и крутить, чтобы это сделать? :-)
MacGyver
3
Разобрался ... При использовании NUnit назовите файл app.config тем же именем, что и имя вашего проекта * .nunit. Так, например, если вы назвали свой проект «ClassLibraryA.nunit», тогда назовите файл конфигурации библиотеки классов «ClassLibraryA.config». Они также должны находиться в той же папке / каталоге. NUnit фактически использует его в качестве основного файла конфигурации .... добавьте ссылку на System.Configuration (на вкладке .NET) .... и используйте этот код: string settingValue = ConfigurationManager.AppSettings ["settingName"];
MacGyver
2
Как бы вы порекомендовали настроить все при проведении интеграционных тестов? Мне кажется логичным иметь app.config в этой тестовой библиотеке со строкой подключения.
Томас Янссон
2
Что делать, если вы не можете настроить приложение, потому что оно вам не принадлежит.
Скачок напряжения,
50

Я не знаю, почему этого ответа еще не было:

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

Вы можете создать app.config в проекте библиотеки классов. Он будет содержать конфигурации по умолчанию для элементов, которые вы создаете в библиотеке. Например, он будет содержать строки подключения, если вы создаете модель Entity Framework в библиотеке классов.

Однако эти настройки не будут использоваться исполняемым приложением, вызывающим библиотеку. Вместо этого эти настройки могут быть скопированы из файла library.dll.config в app.config или web.config вызывающей стороны, чтобы их можно было изменить так, чтобы они соответствовали вызывающей стороне и среде, в которой находится вызывающий объект. развернут.

Так было с .NET с первого дня.

Джон Сондерс
источник
2
Но что мне делать, если мне нужно вызвать функциональность веб-службы из библиотеки классов? VS создал файл app.config по умолчанию, но мое приложение вылетело при попытке вызвать функцию
веб-сервиса
Вы должны скопировать элементы, которые были помещены в библиотеку классов app.config, в app.config или web.config вызывающего объекта библиотеки классов. Это позволяет вызывающему абоненту контролировать конфигурацию. Например, вызывающий теперь может изменить URL-адрес службы, которую вызывает ваша библиотека классов, а ваша библиотека классов даже не узнает об изменении.
Джон Сондерс,
6
@John Saunders: «может понадобиться» - правильные слова. Таким образом, могут возникать ситуации, когда параметры конфигурации различаются только для каждого сервера (например, строки подключения), и удобнее иметь собственную конфигурацию для библиотеки DLL, чем многократно копировать ее для каждой сборки, использующей dll. На мой взгляд, предпочтительное использование Microsoft / .NET не является святым Граалем. На самом деле это зависит от того, что наиболее удобно в сценарии развертывания. Нет нужды отчитывать Тодда, его мнение так же важно, как ваше или Microsoft.
Мне очень интересно это решение - мне оно кажется идеальным. Имеет смысл, что библиотека будет иметь настройки по умолчанию, в то время как приложение будет иметь возможность переопределить их. Не могли бы вы рассказать о том, как настройки могут быть переданы из библиотеки app.config в файл app.config исполняющей сборки, или направили бы меня на соответствующий ресурс?
давка
@crush: Это называется «копировать и вставлять». Строго типизированная функция «Параметры» .NET может немного помочь, поскольку она записывает значения по умолчанию в сборку.
Джон Сондерс
43

Джон, было высказано множество мнений, которые не дали правильного ответа на ваш вопрос.

Я выскажу СВОЕ МНЕНИЕ, а затем расскажу, как сделать именно то, о чем вы просили.

Я не вижу причин, по которым сборка не может иметь собственный файл конфигурации. Почему первый уровень атомики (это настоящее слово?) Находится на уровне приложения? Почему не на уровне решения? Это произвольное решение, основанное на предположении, и как таковое МНЕНИЕ. Если бы вы написали библиотеку журналирования и хотели бы включить для нее файл конфигурации, который будет использоваться глобально, почему бы вам не подключиться к встроенным функциям настроек? Мы все это делали ... пытались предоставить "мощную" функциональность другим разработчикам. Как? Делая предположения, которые по своей сути переводятся в ограничения. Это именно то, что MS сделала с фреймворком настроек, так что вам придется немного его «обмануть».

Чтобы напрямую ответить на ваш вопрос, просто добавьте файл конфигурации вручную (xml) и назовите его, чтобы он соответствовал вашей библиотеке и включил расширение «config». Пример:

MyDomain.Mylibrary.dll.Config

Затем используйте ConfigurationManager для загрузки файла и доступа к настройкам:

string assemblyPath = new Uri(Assembly.GetExecutingAssembly().CodeBase).AbsolutePath;
Configuration cfg = ConfigurationManager.OpenExeConfiguration(assemblyPath);
string result = cfg.AppSettings.Settings["TEST_SETTING"].Value;

Обратите внимание, что это полностью поддерживает иерархию machine.config, даже если вы явно выбрали файл конфигурации приложения. Другими словами, если этого параметра нет, разрешение будет выше. Настройки также переопределяют записи machine.config.

Тодд Больё
источник
3
-1: Ваше мнение само по себе не важно. Факты были бы важны. .NET, начиная с первого дня, создавался так, чтобы вызывающие библиотеки определяли конфигурацию элементов в библиотеке. Это единственное, что имеет смысл для конфигурации, поскольку разные вызывающие библиотеки могут нуждаться в разных конфигурациях.
Джон Сондерс
19
@JohnSaunders «разные вызывающие библиотеки могут нуждаться в разных конфигурациях». Точнее, им «могут» потребоваться разные конфигурации, и ваша логика имеет смысл во всех случаях, когда конфигурация действительно зависит от вызывающего. Но есть несколько случаев, когда конфигурация используется внутри библиотеки классов, и конфигурация точно такая же, независимо от того, что вызывает вызывающий. Если у вас есть 10 приложений, потребляющих библиотеку, будет хуже копировать и вставлять ту же конфигурацию в 10 файлов конфигурации.
wired_in
3
@ToddBeaulieu: Я думаю, вам нужно слово «атомарность».
nicodemus13
3
В архитектуре плагинов действительно имеет смысл, если у всех плагинов есть собственный файл конфигурации.
Даватар
4
@RMuesi Noone сказал, что это никогда не меняется, просто это не зависит от вызывающего пользователя библиотеки. Конфигурация может меняться в зависимости от того, отлаживаете ли вы библиотеку по сравнению с производственной версией. Он может меняться в зависимости от среды, для которой вы строите, и т. Д.
wired_in
6

Фактически, библиотека классов, которую вы реализуете, получает информацию из app.config внутри приложения, которое ее использует, поэтому наиболее правильный способ реализовать конфигурацию для библиотек классов в .net в VS - подготовить app.config в приложение для настройки всего, что оно потребляет, например конфигурации библиотек.

Я немного поработал с log4net и обнаружил, что у того, кто готовил приложение, всегда был раздел для конфигурации log4net внутри основного app.config .

Я надеюсь вы найдете эту информацию полезной.

До встречи и оставляйте комментарии о найденном вами решении.

РЕДАКТИРОВАТЬ:

По следующей ссылке у вас есть app.config с разделом для log4net:

http://weblogs.asp.net/tgraham/archive/2007/03/15/a-realistic-log4net-config.aspx

Амедио
источник
2
+1 Совершенно верно; app.configЗагружаются из самой программы , что в конечном итоге работает ... не отдельные библиотеки классов. Откровенно говоря, немного сбивает с толку, как многие не знают этого самого основного факта.
Эндрю Барбер
Возможно, люди пришли с языка Java и у вас есть файл log4java.properties и отдельный файл свойств для вашего приложения.
Amedio
6

Если вы хотите настроить ведение журнала своего проекта с помощью log4Net при использовании библиотеки классов, нет никакой реальной необходимости в каком-либо файле конфигурации. Вы можете настроить регистратор log4net в классе и использовать этот класс как библиотеку.

Поскольку log4net предоставляет все возможности для его настройки.

Пожалуйста, найдите код ниже.

public static void SetLogger(string pathName, string pattern)
        {
            Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();

            PatternLayout patternLayout = new PatternLayout();
            patternLayout.ConversionPattern = pattern;
            patternLayout.ActivateOptions();

            RollingFileAppender roller = new RollingFileAppender();
            roller.AppendToFile = false;
            roller.File = pathName;
            roller.Layout = patternLayout;
            roller.MaxSizeRollBackups = 5;
            roller.MaximumFileSize = "1GB";
            roller.RollingStyle = RollingFileAppender.RollingMode.Size;
            roller.StaticLogFileName = true;
            roller.ActivateOptions();
            hierarchy.Root.AddAppender(roller);

            MemoryAppender memory = new MemoryAppender();
            memory.ActivateOptions();
            hierarchy.Root.AddAppender(memory);

            hierarchy.Root.Level = log4net.Core.Level.Info;
            hierarchy.Configured = true;
      }

Теперь вместо вызова XmlConfigurator.Configure (new FileInfo ("app.config")) вы можете напрямую вызвать SetLogger с желаемым путем и шаблоном, чтобы установить регистратор в функции запуска приложения Global.asax.

И используйте приведенный ниже код, чтобы зарегистрировать ошибку.

        public static void getLog(string className, string message)
        {
            log4net.ILog iLOG = LogManager.GetLogger(className);
            iLOG.Error(message);    // Info, Fatal, Warn, Debug
        }

Используя следующий код, вам не нужно писать ни одной строчки ни в приложении web.config, ни внутри app.config библиотеки.

Рахул
источник
2
я чувствовал, что это лучший ответ ... вместо того, чтобы обсуждать, следует ли разрешить файл конфигурации для библиотеки ... этот ответ отвечает на вопрос OP об использовании Log4net
saurav
1
Несмотря на то, что в вопросе в качестве примера использовался log4net, на самом деле вопрос касается конфигураций в целом. Я бы сказал, что ответы о log4net на самом деле неуместны.
binki
4

На самом деле, в некоторых редких случаях вы можете хранить app.config в библиотеках классов (добавляя вручную) и анализировать его с помощью OpenExeConfiguration .

 var fileMap =
    new ExeConfigurationFileMap {ExeConfigFilename = 
    @"C:\..somePath..\someName.config"};
 System.Configuration.Configuration config =
    ConfigurationManager.OpenMappedExeConfiguration(fileMap, 
    ConfigurationUserLevel.None);

Вы действительно должны оценить реальную потребность в этом. Для абстрактных данных это не лучшее решение, но «Конфигурационные разделы» могут быть очень полезны !!

Например, мы организовали нашу N-уровневую архитектуру WCF отдельно, без каких-либо метаданных, просто используя контейнер Unity и фабрику инъекций на основе фабрики каналов T. Мы добавили dll externall ClassLibrary только с интерфейсами [Service Contract] и общим app.config по порядку чтобы читать конечные точки из клиентского раздела и легко добавлять / изменять их в одном месте.

Рома Бородов
источник
3

Вы действительно хотите добавить App.config в свою библиотеку классов тестов , если вы используете трассировщик / регистратор. В противном случае ничего не регистрируется, когда вы запускаете тест через средство запуска тестов, такое как TestDriven.Net.

Например, я использую TraceSourceв своих программах, но запущенные тесты ничего не регистрируют, если я не добавлю файл App.config с конфигурацией трассировки / журнала в библиотеку классов тестов.

В противном случае добавление App.config в библиотеку классов ничего не даст.

Даниэль А.А. Пельсмакер
источник
2

Ваш ответ на создание app.config не вручную - это вкладка Visual Studio Project Properties / Settings.

Когда вы добавляете настройку и сохраняете, ваш app.config будет создан автоматически. На этом этапе создается куча кода в пространстве имен { yourclasslibrary .Properties}, содержащем свойства, соответствующие вашим настройкам. Сами настройки будут помещены в настройки app.config applicationSettings.

 <configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
        <section name="ClassLibrary.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup>
</configSections>
<applicationSettings>
    <ClassLibrary.Properties.Settings>
        <setting name="Setting1" serializeAs="String">
            <value>3</value>
        </setting>
    </BookOneGenerator.Properties.Settings>
</applicationSettings>

Если вы добавили параметр области действия приложения с именем Setting1 = 3, то будет создано свойство с именем Setting1. Эти свойства становятся при компиляции частью двоичного файла и украшаются атрибутом DefaultSettingValueAttribute, которому присвоено значение, указанное вами во время разработки.

     [ApplicationScopedSetting]
    [DebuggerNonUserCode]
    [DefaultSettingValue("3")]
    public string Setting1
    {
        get
        {
            return (string)this["Setting1"];
        }
    }

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

Это произойдет, когда мы правильно настроим исполняемый файл app.config. Два шага. 1. мы сообщаем, что у нас будет раздел настроек для этой библиотеки классов и 2. с небольшими изменениями мы вставляем файл конфигурации библиотеки классов в исполняемую конфигурацию. (есть метод, в котором вы можете сохранить внешний файл конфигурации библиотеки классов и просто ссылаться на него из файла config.

Итак, у вас может быть app.config для библиотеки классов, но он бесполезен, если вы не интегрируете его должным образом с родительским приложением. Посмотрите, что я написал некоторое время назад: ссылка

Мирча Ион
источник
1

При добавлении проекта библиотеки классов в решение не происходит автоматического добавления файла app.config.

Насколько мне известно, нет никаких указаний на то, что это нужно делать вручную. Я думаю, это обычное дело.

Что касается конфигурации log4Net, вам не нужно помещать конфигурацию в app.config, вы можете иметь специальный файл conf в вашем проекте, а также файл app.config одновременно.

эта ссылка http://logging.apache.org/log4net/release/manual/configuration.html предоставит вам примеры обоих способов (раздел в app.config и автономный файл конфигурации log4net)

Бруно
источник
Ничего не повредит добавить app.configв проект библиотеки, нет. Но и не будет использоваться.
Эндрю Барбер
1
@AndrewBarber Он будет использоваться в тестовом проекте. См. Stackoverflow.com/a/31389495
binki
0

Я бы рекомендовал использовать Properties.Settings для хранения таких значений, как ConnectionStrings и т. Д., Внутри библиотеки классов. Здесь все строки подключения хранятся по предложению Visual Studio, например, при попытке добавить адаптер таблицы. введите описание изображения здесь

И тогда они будут доступны, используя этот код везде в библиотеке clas.

var cs=  Properties.Settings.Default.[<name of defined setting>];
сишанов
источник