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


83

Я не бачу файл app.config, створений для бібліотеки класів майстром VS2008. У своєму дослідженні я виявив, що в додатку існує лише одне app.config.

Це погано додавати app.config вручну до бібліотеки класів чи є інші методи, які слугуватимуть цілі app.config у бібліотеці класів?

Мені потрібно зберігати інформацію про конфігурацію log4net у файлі app.config.


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 02

2
Як би ви рекомендували налаштовувати ситуацію під час тестів інтеграції? Для мене представляється логічним наявність app.config у цій тестовій бібліотеці із рядком підключення.
Томаш Янссон

2
Що робити, якщо ви не можете налаштувати програму, оскільки не є її власником.
Спалах напруги

50

Не знаю, чому ця відповідь ще не дана:

Взагалі, різні абоненти однієї бібліотеки використовуватимуть різні конфігурації. Це означає, що конфігурація повинна знаходитись у виконуваній програмі, а не в бібліотеці класів.

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

Однак ці налаштування не будуть використовуватися виконуваною програмою, що викликає бібліотеку. Натомість ці налаштування можна скопіювати з файлу library.dll.config у app.config або web.config абонента, щоб їх можна було змінити, щоб вони були специфічними для абонента та середовища, в яке абонент розгорнуто.

Так було з .NET з 1-го дня.


2
Але що мені робити, якщо мені потрібно зателефонувати до функціоналу веб-сервісу з бібліотеки класів? VS створив за замовчуванням app.config, але моя програма зазнала аварії при спробі викликати функцію веб-служби - вона не може знайти записи конфігурації ...
Laserson

Вам потрібно скопіювати елементи, розміщені в бібліотеці класів app.config, у app.config або web.config абонента бібліотеки класів. Це дозволяє абоненту контролювати конфігурацію. Наприклад, абонент тепер може змінити URL-адресу служби, яку викликає ваша бібліотека класів, а ваша бібліотека класів навіть не знатиме про зміну.
Джон Сондерс,

6
@ Джон Сондерс: "можливо, знадобиться" - це саме правильні слова. Тож можуть бути ситуації, коли налаштування конфігурації відрізняються лише для кожного сервера (наприклад, рядки підключення), і зручніше мати DLL власну конфігурацію, ніж копіювати її багато разів для кожної збірки, яка використовує DLL. На мою думку Microsofts / .NET вподобане використання - це не святий Грааль. Це насправді залежить від того, що найзручніше у сценарії розгортання. Не потрібно відмовляти Тодда, його думка настільки важлива, як ваша або Microsofts.

Мене дуже цікавить це рішення - воно для мене звучить ідеально. Має сенс, що бібліотека буде мати налаштування за замовчуванням, тоді як програма зможе їх замінити. Чи могли б ви розширити інформацію про те, як параметри можуть бути розповсюджені з бібліотеки 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, починаючи з 1-го дня, був створений таким чином, щоб абоненти бібліотеки визначали конфігурацію елементів у бібліотеці. Це єдине, що має реальний сенс для конфігурації, оскільки різним абонентам бібліотеки можуть знадобитися різні конфігурації.
Джон Сондерс,

19
@JohnSaunders "різним абонентам бібліотеки можуть знадобитися різні конфігурації". Точно, їм "можуть" потрібні різні конфігурації, і ваша логіка має цілком сенс у всіх випадках, коли конфігурація дійсно залежить від абонента. Але є кілька випадків, коли конфігурація використовується внутрішньо для бібліотеки класів, і конфігурація абсолютно однакова, незалежно від того, хто викликає. Якщо у вас є 10 програм, які використовують бібліотеку, скопіювати та вставити ту саму конфігурацію в 10 конфігураційних файлів має бути гірше.
wired_in

3
@ToddBeaulieu: Я думаю, що слово, яке ви хочете, це "атомність".
nicodemus13

3
В архітектурі плагінів справді має сенс, якщо всі плагіни мають власний конфігураційний файл.
Даватар

4
@RMuesi Ніхто не сказав, що це ніколи не змінюється, просто це не залежить від того, хто викликає бібліотеку. Конфігурація може змінюватися залежно від того, чи ви налагоджуєте бібліотеку порівняно з виробничим випуском. Це може змінюватися залежно від середовища, для якого ви будуєте тощо,
wired_in

6

Насправді бібліотека класів, яку ви реалізуєте, отримує інформацію з app.config усередині програми, яка її споживає, отже, найбільш правильним способом реалізації конфігурації для бібліотек класів у .net у VS є підготовка app.config у додаток для налаштування всього, що споживає, наприклад, конфігурації бібліотек.

Я трохи попрацював з log4net, і виявив, що той, хто готував додаток, завжди мав розділ для конфігурації log4net всередині main 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 (новий 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
я вважав, що це найкраща відповідь ... замість того, щоб обговорювати, чи слід дозволяти файл конфігурації для бібліотеки ... ця відповідь відповідає на питання ОП щодо використання 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-Tier WCF, відокремлену без будь-яких метаданих, просто використовуючи Unity Container and Injection Factory на основі Channel Factory T. Ми додали зовнішню DLL ClassLibrary лише з інтерфейсом [Service Contract] та загальним app.config для того, щоб читати кінцеві точки з клієнтської секції та легко додавати / змінювати їх в одному місці.


3

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

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

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


2

Ваша відповідь за неручне створення app.config - це вкладка Властивості / налаштування проекту Visual Studio.

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

 <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. з невеликими змінами ми вставляємо конфігураційний файл бібліотеки класів у виконуваний конфігураційний файл. (існує метод, за допомогою якого ви можете зберігати конфігураційний файл бібліотеки класів зовнішнім, і ви просто посилаєтесь на нього з конфігурації виконуваного файлу.

Отже, ви можете мати app.config для бібліотеки класів, але це марно, якщо ви неправильно інтегруєте його з батьківським додатком. Подивіться тут, що я писав колись тому: посилання


1

Немає автоматичного додавання файлу app.config, коли ви додаєте проект бібліотеки класів до свого рішення.

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

Щодо конфігурації log4Net, вам не потрібно поміщати конфігурацію в app.config, ви можете одночасно мати у своєму проекті спеціальний файл конф, а також файл app.config.

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


Нічого не завадить додати проект app.configдо бібліотечного проекту, ні. Але він також не буде використаний.
Ендрю Барбер

1
@AndrewBarber Це буде використано в тестовому проекті. Див stackoverflow.com/a/31389495
Бінки

0

Я б рекомендував використовувати Properties.Settings для зберігання таких значень, як ConnectionStrings тощо у бібліотеці класів. Тут зберігаються всі рядки підключень за пропозицією Visual Studio при спробі додати адаптер таблиці, наприклад. введіть тут опис зображення

І тоді вони будуть доступні за допомогою цього коду скрізь у бібліотеці clas

var cs=  Properties.Settings.Default.[<name of defined setting>];
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.