app.config dla biblioteki klas

83

Nie widzę pliku app.config wygenerowanego dla biblioteki klas przez kreatora VS2008. W moich badaniach odkryłem, że w aplikacji istnieje tylko jeden plik app.config.

Czy ręczne dodawanie pliku app.config do biblioteki klas jest złą rzeczą, czy też istnieją inne metody, które będą służyć jako plik app.config w bibliotece klas?

Muszę przechowywać informacje konfiguracyjne log4net w pliku app.config.

logeeks
źródło
3
Możesz odczytać plik konfiguracyjny projektu wykonywalnego z biblioteki.
Akram Shahda

Odpowiedzi:

102

Generalnie nie należy dodawać app.configpliku do projektu biblioteki klas; nie będzie używany bez bolesnego zginania i skręcania z twojej strony. W ogóle nie szkodzi projektowi biblioteki - po prostu nic nie da.

Zamiast tego konfigurujesz aplikację, która korzysta z Twojej biblioteki; więc wymagane informacje o konfiguracji będą tam trafiać. Każda aplikacja, która może korzystać z Twojej biblioteki, prawdopodobnie będzie miała inne wymagania, więc ma to również sens.

Andrew Barber
źródło
23
Dobrze dla ciebie. Jednak nie odpowiadałem na twoje pytanie. Najwyraźniej masz jakiś własny system konfiguracji, który nie dotyczy osoby zadającej tutaj pytanie.
Andrew Barber
1
Mam bibliotekę klas Selenium WebDriver, którą uruchamiam z NUnit dla wszystkich moich przypadków testowych. Wolałbym nie martwić się konfiguracją w NUnit. Jak mogę zginać i przekręcać, aby to zrobić? :-)
MacGyver
3
Rozgryzłem to ... Jeśli używasz NUnit, nazwij swój plik app.config taką samą nazwą jak nazwa pliku projektu * .nunit. Na przykład, jeśli nazwałeś swój projekt „ClassLibraryA.nunit”, nazwij plik konfiguracyjny biblioteki klas „ClassLibraryA.config”. Muszą również znajdować się w tym samym folderze / katalogu. NUnit używa tego jako głównego pliku konfiguracyjnego .... dodaj odniesienie do System.Configuration (na karcie .NET) .... i użyj tego kodu: string settingValue = ConfigurationManager.AppSettings ["settingName"];
MacGyver
2
Jak poleciłbyś konfigurację podczas testów integracyjnych? Wydaje mi się logiczne, że w tej bibliotece testowej plik app.config z parametrami połączenia.
Tomas Jansson,
2
Co jeśli nie możesz skonfigurować aplikacji, ponieważ nie jesteś jej właścicielem.
Skok napięcia
50

Nie wiem, dlaczego ta odpowiedź nie została jeszcze udzielona:

Różni wywołujący z tej samej biblioteki będą na ogół używać różnych konfiguracji. Oznacza to, że konfiguracja musi znajdować się w aplikacji wykonywalnej , a nie w bibliotece klas.

Możesz utworzyć plik app.config w ramach projektu biblioteki klas. Będzie zawierać domyślne konfiguracje dla elementów tworzonych w bibliotece. Na przykład będzie zawierał parametry połączenia, jeśli utworzysz model Entity Framework w bibliotece klas.

Jednak te ustawienia nie będą używane przez aplikację wykonywalną wywołującą bibliotekę. Zamiast tego te ustawienia można skopiować z pliku library.dll.config do pliku app.config lub web.config wywołującego, aby można je było zmienić tak, aby były specyficzne dla dzwoniącego i środowiska, w którym dzwoniący jest rozmieszczony.

Tak jest z .NET od pierwszego dnia.

John Saunders
źródło
2
Ale co powinienem zrobić, jeśli muszę wywołać funkcję serwera internetowego z biblioteki klas? VS utworzył domyślny plik app.config, ale moja aplikacja uległa awarii podczas próby wywołania funkcji usługi sieciowej - nie może znaleźć wpisów konfiguracyjnych ...
Laserson
Musisz skopiować elementy, które zostały umieszczone w bibliotece klas app.config do pliku app.config lub web.config obiektu wywołującego bibliotekę klas. Dzięki temu dzwoniący ma kontrolę nad konfiguracją. Na przykład wywołujący może teraz zmienić adres URL usługi wywoływanej przez bibliotekę klas, a biblioteka klas nawet nie będzie wiedzieć o zmianie.
John Saunders,
6
@John Saunders: „może potrzebować” to właściwe słowa. Mogą więc zaistnieć sytuacje, w których ustawienia konfiguracyjne różnią się tylko w zależności od serwera (np. Parametry połączenia) i wygodniej jest mieć bibliotekę dll z własną konfiguracją, niż kopiować ją wiele razy dla każdego zestawu używającego biblioteki dll. Moim zdaniem preferowane użycie Microsoftu / .NET nie jest świętym Graalem. To naprawdę zależy, co jest najwygodniejsze w scenariuszu wdrożenia. Nie ma potrzeby, żeby Todda się przejmować, jego opinia jest równie ważna jak Twoja czy Microsofts.
Bardzo mnie to rozwiązanie interesuje - brzmi dla mnie idealnie. Sensowne jest, aby biblioteka zawierała ustawienia domyślne, podczas gdy aplikacja miałaby możliwość ich nadpisania. Czy możesz rozwinąć, w jaki sposób ustawienia mogą być propagowane z pliku app.config biblioteki do pliku app.config zestawu wykonawczego, czy skierować mnie do odpowiedniego zasobu?
zmiażdżyć
@crush: Nazywa się „kopiuj i wklej”. Funkcja ustawień z silnym typem .NET może nieco pomóc, ponieważ wprowadza wartości domyślne do zestawu.
John Saunders,
43

Jon, wydano wiele opinii, które nie były poprawną odpowiedzią na twoje pytanie.

Przekażę MOJĄ OPINIĘ, a następnie powiem ci, jak zrobić dokładnie to, o co prosiłeś.

Nie widzę powodu, dla którego zespół nie mógłby mieć własnego pliku konfiguracyjnego. Dlaczego pierwszy poziom atomicy (czy to prawdziwe słowo?) Znajduje się na poziomie aplikacji? Dlaczego nie na poziomie rozwiązania? To arbitralna decyzja oparta na najlepszym przypuszczeniu i jako taka OPINIA. Jeśli miałbyś napisać bibliotekę rejestrowania i chciałbyś dołączyć do niej plik konfiguracyjny, który byłby używany globalnie, dlaczego nie mógłbyś podłączyć się do wbudowanej funkcji ustawień? Wszyscy to zrobiliśmy ... próbowaliśmy zapewnić „potężną” funkcjonalność innym programistom. W jaki sposób? Przyjmując założenia, które nieodłącznie przekładają się na ograniczenia. To jest dokładnie to, co MS zrobił z frameworkiem ustawień, więc musisz trochę "oszukać".

Aby bezpośrednio odpowiedzieć na pytanie, po prostu dodaj ręcznie plik konfiguracyjny (xml) i nazwij go tak, aby pasował do Twojej biblioteki i zawierał rozszerzenie „config”. Przykład:

MyDomain.Mylibrary.dll.Config

Następnie użyj menedżera konfiguracji, aby załadować plik i uzyskać dostęp do ustawień:

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

Zauważ, że to w pełni obsługuje heierarchię machine.config, nawet jeśli jawnie wybrałeś plik konfiguracyjny aplikacji. Innymi słowy, jeśli ustawienia nie ma, rozwiąże to wyżej. Ustawienia zastąpią również wpisy machine.config.

Todd Beaulieu
źródło
3
-1: Twoja opinia sama w sobie nie jest ważna. Fakty byłyby ważne. .NET, od pierwszego dnia, został stworzony, aby wywołujący bibliotekę określali konfigurację elementów w bibliotece. To jedyna rzecz, która ma sens podczas konfiguracji, ponieważ różni wywołujący bibliotekę mogą potrzebować różnych konfiguracji.
John Saunders
19
@JohnSaunders „różni użytkownicy biblioteki mogą potrzebować różnych konfiguracji”. Dokładnie, „mogą” wymagać różnych konfiguracji, a Twoja logika ma sens we wszystkich przypadkach, w których konfiguracja zależy od dzwoniącego. Ale jest kilka przypadków, w których konfiguracja jest używana wewnętrznie dla biblioteki klas, a konfiguracja jest dokładnie taka sama, bez względu na to, kim jest wywołujący. Jeśli masz 10 aplikacji korzystających z biblioteki, musi być gorzej skopiować i wkleić dokładnie tę samą konfigurację do 10 plików konfiguracyjnych.
wired_in
3
@ToddBeaulieu: Myślę, że słowo, które chcesz, to „atomowość”.
nicodemus 13
3
W architekturze wtyczek rzeczywiście ma sens, jeśli wszystkie wtyczki mają własny plik konfiguracyjny.
Davatar
4
@RMuesi Nikt nie powiedział, że to się nigdy nie zmienia, tylko że nie zależy to od osoby dzwoniącej do biblioteki. Konfiguracja może się zmieniać w zależności od tego, czy debugujesz bibliotekę, czy wersję produkcyjną. Może się zmienić w zależności od środowiska, dla którego
budujesz
6

W rzeczywistości implementowana biblioteka klas pobiera informacje z app.config wewnątrz aplikacji, która je zużywa, więc najbardziej poprawnym sposobem implementacji konfiguracji dla bibliotek klas w .net w VS jest przygotowanie pliku app.config w aplikacja do konfigurowania wszystkiego, co zużywa, na przykład konfiguracja bibliotek.

Pracowałem trochę z log4net i odkryłem, że ten, który przygotował aplikację, zawsze miał sekcję konfiguracji log4net w głównym pliku app.config .

Mam nadzieję, że te informacje były przydatne.

Do zobaczenia i opublikuj komentarze na temat znalezionego rozwiązania.

EDYTOWAĆ:

W następnym linku masz plik app.config z sekcją dla log4net:

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

Amedio
źródło
2
+1 Dokładnie; app.configJest ładowany od rzeczywistego programu, który ostatecznie prowadzi ... nie poszczególne biblioteki klas. Szczerze mówiąc, to trochę zagmatwane, ilu nie wie o tym podstawowym fakcie.
Andrew Barber
Być może ludzie pochodzą z języka Java i masz tam plik log4java.properties i oddzielny plik właściwości dla swojej aplikacji.
Amedio,
6

Jeśli chcesz skonfigurować rejestrowanie projektu za pomocą log4Net, korzystając z biblioteki klas, nie ma potrzeby posiadania żadnego pliku konfiguracyjnego. Możesz skonfigurować swój rejestrator log4net w klasie i używać tej klasy jako biblioteki.

Ponieważ log4net zapewnia wszystkie opcje konfiguracji.

Proszę znaleźć kod poniżej.

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;
      }

Teraz zamiast wywoływać XmlConfigurator.Configure (new FileInfo ("app.config")) możesz bezpośrednio wywołać SetLogger z żądaną ścieżką i wzorcem, aby ustawić rejestrator w funkcji uruchamiania aplikacji Global.asax.

I użyj poniższego kodu, aby zarejestrować błąd.

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

Używając poniższego kodu, nie musisz pisać ani jednej linii ani w aplikacji web.config, ani w app.config biblioteki.

Rahul
źródło
2
Czułem, że to najlepsza odpowiedź ... zamiast dyskutować, czy plik konfiguracyjny powinien być dozwolony dla biblioteki ... ta odpowiedź odpowiada na pytanie OP dotyczące korzystania z Log4net
saurav
1
Mimo że w pytaniu użyto log4net jako przykładu, rzeczywiste pytanie dotyczy ogólnie konfiguracji. Powiedziałbym, że odpowiedzi na temat log4net są właściwie nieistotne.
binki
4

Właściwie w rzadkich przypadkach można przechowywać plik app.config w bibliotekach klas (dodając go ręcznie) i przeanalizować go przez OpenExeConfiguration .

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

Naprawdę powinieneś oszacować rzeczywistą potrzebę tego. W przypadku danych abstrakcyjnych nie jest to najlepsze rozwiązanie, ale „Sekcje konfiguracyjne” mogą być bardzo przydatne !!

Na przykład zorganizowaliśmy naszą niezależną architekturę WCF N-Tier, bez żadnych metadanych, po prostu za pomocą Unity Container i Injection Factory w oparciu o Channel Factory T. Dodaliśmy zewnętrzną bibliotekę DLL ClassLibrary z interfejsami [Service Contract] i wspólną konfiguracją app.config w kolejności czytać punkty końcowe z sekcji klientów i łatwo dodawać / zmieniać je w jednym miejscu.

Roma Borodov
źródło
3

Chcesz dodać App.config do swojej biblioteki klas testów , jeśli używasz śledzenia / rejestratora. W przeciwnym razie nic nie zostanie zarejestrowane po uruchomieniu testu za pomocą programu uruchamiającego testy, takiego jak TestDriven.Net.

Na przykład używam TraceSourcew moich programach, ale uruchamianie testów nie rejestruje niczego, chyba że dodam plik App.config z konfiguracją śledzenia / dziennika również do biblioteki klas testowych.

W przeciwnym razie dodanie App.config do biblioteki klas nic nie da.

Daniel AA Pelsmaeker
źródło
2

Odpowiedzią na nie ręczne tworzenie pliku app.config jest karta Właściwości / Ustawienia projektu programu Visual Studio.

Gdy dodasz ustawienie i zapiszesz, plik app.config zostanie utworzony automatycznie. W tym momencie część kodu jest generowana w przestrzeni nazw { yourclasslibrary .Properties} zawierającej właściwości odpowiadające Twoim ustawieniom. Same ustawienia zostaną umieszczone w ustawieniach applicationSettings pliku 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>

Jeśli dodano ustawienie w zakresie aplikacji o nazwie Setting1 = 3, zostanie utworzona właściwość o nazwie Setting1. Te właściwości stają się częścią kompilacji pliku binarnego i są ozdobione DefaultSettingValueAttribute, który jest ustawiony na wartość określoną w czasie projektowania.

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

Tak więc, tak jak w kodzie biblioteki klas, używasz tych właściwości, jeśli odpowiednie ustawienie nie istnieje w pliku konfiguracyjnym środowiska uruchomieniowego, zostanie zastosowana wartość domyślna. W ten sposób aplikacja nie ulegnie awarii z powodu braku wpisu ustawień, co jest bardzo mylące za pierwszym razem, gdy nie wiesz, jak te rzeczy działają. Teraz zadajesz sobie pytanie, w jaki sposób można określić naszą własną nową wartość we wdrożonej bibliotece i uniknąć użycia domyślnej wartości ustawienia?

Stanie się tak, gdy odpowiednio skonfigurujemy plik app.config. Dwa kroki. 1. informujemy, że będziemy mieć sekcję ustawień dla tej biblioteki klas i 2. z niewielkimi modyfikacjami wklejamy plik konfiguracyjny biblioteki klas do wykonywalnej konfiguracji. (istnieje metoda, w której możesz zachować zewnętrzny plik konfiguracyjny biblioteki klas i po prostu odwołać się do niego z pliku config.

Możesz więc mieć plik app.config dla biblioteki klas, ale jest on bezużyteczny, jeśli nie zintegrujesz go poprawnie z aplikacją nadrzędną. Zobacz, co kiedyś napisałem: link

Mircea Ion
źródło
1

Po dodaniu projektu biblioteki klas do rozwiązania nie ma automatycznego dodawania pliku app.config.

O ile mi wiadomo, nie ma przeciwwskazań dotyczących robienia tego ręcznie. Myślę, że to powszechne użycie.

Jeśli chodzi o konfigurację log4Net, nie musisz umieszczać konfiguracji w app.config, możesz mieć dedykowany plik conf w swoim projekcie, a także plik app.config w tym samym czasie.

ten link http://logging.apache.org/log4net/release/manual/configuration.html zawiera przykłady dotyczące obu sposobów (sekcja w app.config i samodzielny plik konfiguracyjny log4net)

Bruno
źródło
Dodanie app.configdo projektu biblioteki nic nie zaszkodzi , nie. Ale też nie będzie używany.
Andrew Barber
1
@AndrewBarber Będzie używany w projekcie testowym. Zobacz stackoverflow.com/a/31389495
binki
0

Polecam użycie Properties.Settings do przechowywania wartości, takich jak ConnectionStrings i tak dalej, w bibliotece klas. Jest to miejsce, w którym wszystkie parametry połączenia są przechowywane na podstawie sugestii z programu Visual Studio, na przykład podczas próby dodania adaptera tabeli. wprowadź opis obrazu tutaj

A potem będą dostępne za pomocą tego kodu w każdym miejscu w bibliotece clas

var cs=  Properties.Settings.Default.[<name of defined setting>];
sishanov
źródło