Frage

Ich schrieb vor kurzem eine DLL in C # (.NET 2.0), die eine Klasse enthält, die eine IP-Adresse benötigt. Ein Mitarbeiter von mir die Klasse geändert, um die IP von einem „.dll.config“ (XML) Datei abzurufen - Diese scheinbar durch die ‚Application Settings‘ Datei, die er erstellt (Settings1.settings) automatisch generiert. Der Vorteil davon war der Endbenutzer zu ermöglichen, in der XML / config-Datei an die IP-Adresse zu ändern.

Leider, wenn ich seinen Code aus dem Baum zu überprüfen und versuchen (oder verwenden), um diesen neuen Code zu kompilieren, jede Anwendung, die diese DLL Aufruf bekommt nur den Standardwert, eher als der Wert aus der Datei.

Der Konstruktor, der die Konfigurationsdatei ruft sieht wie folgt aus:

    public class form : System.Windows.Forms.Form
    {
        public form()
        {
            // This call is required by the Windows Form Designer.
            InitializeComponent();
            IP = IPAddress.Parse(Settings1.Default.IPAddress);
        }
    }

Ich fand ein Hinweis auf dieses Problem auf den MSDN-Foren , wo ein Benutzer sagte:

  

die ‚alten‘ Werte (die, die Sie zum Zeitpunkt der Entwicklung definieren) sind hart codiert. Wenn die franework nicht in der Lage für den Zugriff auf oder die Konfigurationsdatei öffnen wird es die Standardeinstellung stattdessen verwenden. Dies wird immer passieren, wenn Sie Einstellungen in einer DLL verwenden.

  1. Bedeutet dies, dass ich nicht einen externen Wert für eine DLL in einer Konfigurationsdatei speichern kann? (Mein Mitarbeiter hat irgendwie diese Arbeit gemacht ...)

  2. Da mein Rahmen die Config-Datei zuzugreifen oder zu öffnen, um nicht in der Lage scheint, wie kann ich herausfinden, warum es versagt? Oder auch erkennen, wenn dies geschieht?

Decker : Das hilft ein wenig. Leider schreibe ich diese DLL auf eine Spezifikation, so dass ich eigentlich keinen Zugriff auf die Konfigurationsdatei der Anwendung haben. Wie Sie oben beachten werden, erstellt meine Mitarbeiter ein „Einstellungen 1 .settings“ -Datei. Ich habe das damals nicht verstehen, aber es scheint nun, dass die „1“ Hinzufügen es aus dem Einstellung Raum von jeder Anwendung hält, die es nennt.

Ich denke, was ich versuche, herauszufinden, warum die DLL scheint nicht die Config-Datei zu finden, neben ihm im selben Verzeichnis sitzen. Tracing durch den Code Schritt-für-Schritt verrät nichts.

Als beiseite, kann ich den „Ausgabetyp“ ändere meine Montage von „Klassenbibliothek“ auf „Windows-Anwendung“ und fügen Sie die folgenden Zeilen am Anfang meines DLL-Code:

    [STAThread]
    public static void Main(string[] args)
    {
        System.Windows.Forms.Application.Run(new form());
    }

Wenn ich dies ausführen, erzeugt es eine andere Konfigurationsdatei (ein „.exe.config“) und dass man sich ändern kann, und hat es die neuen Daten aus der Datei ziehen. Also ich bin ein wenig verwirrt. Irgendwelche Ideen?

War es hilfreich?

Lösung

Ich bin Adressierung genau dieses Problems in einer Anwendung, die ich in der Mitte des Prototyping bin. Obwohl Decker Vorschlag der Konfigurationsdateien zusammen Hacking arbeiten soll ich denke, das ist eine ziemlich unbequeme manuelle Hack ist als Teil eines Build-Zyklus durchzuführen. Statt dessen habe ich beschlossen, dass die sauberste Lösung einfach ist jede Bibliothek zu haben, seine eigene library.dll.config Datei zu analysieren. Es ist immer noch nicht perfekt und es erfordert einige zusätzliche Kesselblech Code, aber es scheint der einzige Weg zu sein, um die byzantinische Weise zu erhalten, dass .Net diese app.config-Dateien verarbeitet.

Andere Tipps

Ich verwende diese Technik aller Zeiten Zeit. Oft habe ich eine Bibliothek Assembly, die bestimmten Einstellungen erfordert, und ich brauche sie beide festgelegt durch Projekte als auch die primären „ausführbar“ Baugruppen zu testen - ob Web-Projekte oder Windows Service-Projekte

.

Sie sind richtig, dass, wenn Sie ein Einstellungen für jedes Projekt-Datei erstellen, fügt eine Anwendung config-Datei. Der Wert, den Sie für jede Einstellung eingeben, wird an zwei Orten gespeichert - die Konfigurationsdatei und in Attributen auf den Klassen durch die Einstellungen Infrastruktur. Wenn eine Konfigurationsdatei nicht gefunden wird, die in den Attributen eingebettet Werte verwendet werden.

Hier ist ein Ausschnitt, der ein solches Attribut zeigt:

Hier ist ein Ausschnitt, der den Standardwert des ConcordanceServicesEndpointName in der generierten Klasse zeigt:

    [global::System.Configuration.ApplicationScopedSettingAttribute()]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Configuration.DefaultSettingValueAttribute("InternalTCP")]

    public string ConcordanceServicesEndpointName {
        get {
            return ((string)(this["ConcordanceServicesEndpointName"]));
        }
    }

Was möchten Sie tun ist kopieren Sie den Konfigurationsabschnitt aus der app.config-Datei aus der Bibliothek Montage, und verschmelzen (vorsichtig) in den geltenden web.config oder app.config für die Hauptbaugruppe. Zur Laufzeit, das ist die einzige Konfigurationsdatei, die verwendet wird.

Hier ist ein Beispiel:

<configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
      <section name="LitigationPortal.Documents.BLL.DocumentsBLLSettings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup>
  </configSections>
  <applicationSettings>
    <LitigationPortal.Documents.BLL.DocumentsBLLSettings>
      <setting name="ConcordanceServicesEndpointName" serializeAs="String">
        <value>InternalTCP</value>
      </setting>
    </KayeScholer.LitigationPortal.Documents.BLL.DocumentsBLLSettings>
  </applicationSettings>

Sie sollten diese Abschnitte in die „true“ config-Datei kopieren.

Ich habe das gleiche Problem für eine lange Zeit habe -. Es ist ärgerlich

Ich mag die Idee der eigene Konfigurationsdatei zu machen und mit jedem DLL es analysiert, obwohl es immer noch einfach sein könnte, die verpassen die Config zu ändern.

Eine Sache, die ich in der Vergangenheit zumindest getan habe, damit dies ein wenig leichter ist, um sicherzustellen, dass alle Konfigurationswerte, die die Setting1.Settings Datei ungültig sind.

Zum Beispiel habe ich eine Klasse, die LINQ-To-SQL verwendet, um die DB zu sprechen. So hat es eine Setting1.settings Datei, dass sie die Verbindungszeichenfolge Datenbank speichern in. Der Standardwert, der (nach Ziehen und Ablegen der Datenbank-Tabellen in den Designer) ist die Verbindungszeichenfolge der Entwickler-Datenbank eingegeben wird.

Sobald ich die DBML-Datei aus der Testdatenbank erstellt basiert, kann ich gehen und bearbeiten Sie die Einstellungen-Datei und geben Sie einen Datenbanknamen wie „FAKE_DATABASE“.

So, wenn Sie die DLL in einem anderen Projekt verwenden, und dann vergessen, die Konfigurationsdateien fusionieren in dem richtigen Konfigurationswert für die DLL hinzufügen, zumindest werden Sie eine Fehlermeldung, so etwas wie „Kann keine Verbindung zu FAKE_DATABASE bekommen “.

Natürlich, wenn Sie mit dem Designer wieder arbeiten, werden Sie den Wert wieder auf den Wert Ihrer dev Datenbank ändern.

Sehr große Schmerzen. Sie haben Gotta ändern dies irgendwie.

Anscheinend Ihre Anwendung versucht, aus der Standard-Konfigurationsdatei zu lesen (was wahrscheinlich die Config-Datei der Anwendung ist). Um sicher zu gehen, fügen Sie das Schlüssel-Wert-Paar in der Konfigurationsdatei der DLL in die Config-Datei der Anwendung, führen Sie die Anwendung und sehen, ob es dieses Mal gelesen wird.

Ich glaube, ich habe gerade eine Erklärung, warum dies ist für meine DLL und meine Testanwendung funktioniert nicht. Hier ist die abschließende Ausnahme von einigen Blog Kerl:

  

Die Lösung für dieses ist entweder auf Ihre Bewerbung und die Stützvorrichtungen haben den gleichen Namensraum stellen Sie sicher, oder um sicherzustellen, dass Sie die Inhalte von AppName.exe.config und DllName.dll.config fusionieren (ja, wenn Sie eine DLL kompilieren jetzt erzeugt er diese Datei, aber es wird ignoriert, wenn Sie es auf das Anwendungsverzeichnis kopieren und ist nicht automatisch fusionierten)

Also entweder ich habe die DLL und Anwendung im gleichen Namensraum halten -oder ich den Inhalt der DLL-Konfigurationsdatei mit der Anwendung config-Datei zusammenführen lassen.

(Ist nicht diese Art der Niederlage der Zweck der DLL? Ich dachte, ein DLL sollte eine unabhängige Bibliothek.)

Vielleicht ist dies, warum es für meine Mitarbeiter arbeitet. Die Produktionsanwendung teilt den gleichen Namensraum wie die DLL. (My Test-App eindeutig nicht ...)

UPDATE: Ich saß gerade vor kurzem mit meinen Mitarbeitern nach unten und sprach wieder über dieses Problem und es scheint, dass es nie für ihn entweder arbeitet, aber er hatte es nicht bemerkt, weil er hatte stellen Sie den Anfangswert das gleiche wie das Gerät zu sein, die wir verwenden wollten. So selbstverständlich erschien es zunächst zu arbeiten, aber sobald wir es an anderer Stelle mit leicht unterschiedlichen Einstellungen entfalten es wieder gebrochen wurde.

Ich habe ein ähnliches Problem gesehen bei der Verwendung von app.config. Versuchen Sie, Ihre Anwendung von der EXE läuft anstelle von Visual Studio & sehen, ob es dann verhält sich wie erwartet.

Es ist möglich, dass in dem DLL Sie die Zugriffsmodifizierer haben (für die Settings1.Settings) auf Internal (Friend für VB). Versuchen Sie, die Zugriffsmodifikator zu öffentlichen verändern und sehen, ob das Ihre Anwendung Schreibwerte lesen / können aus dll config.

Die Antwort von Howard deckt die Theorie.

Eine schnelle und schmutzige Art und Weise dies zu lösen, ist die XML-Konfigurationsdatei manuell zu analysieren.

    string configFile = Assembly.GetExecutingAssembly().Location + ".config";
    XDocument.Load(configFile).Root.Element("appSettings")....

Der Fehler, den ich glaube, Sie alle machen ist, dass Sie scheinbar referece auf die DLL-Einstellungen über Settings1.Default.IPAddress machen, während Sie einfach suppossed sind diese Settings1.IPAddress zu tun.

Der Unterschied ist, dass, wenn Sie Settings1.Default.IPAddress die Werte verwenden, werden von den fest codierten Werte in der Baugruppendatei (DLL oder EXE) als Attribut [global :: System.Configuration.DefaultSettingValueAttribute (...)] Imbeded bekommen.

Während Settings1.IPAddress ist der Wert, der in der Datei .dll.config (XML-Datei) ** bearbeitet werden kann. so alle Änderungen an die XML-Datei zu machen, wird es nicht in fest einprogrammierten Standardwert in der Versammlung wider.

Nicht folgt aus:

IP = IPAddress.Parse(Settings1.Default.IPAddress);

Aber versuchen Sie dies:

*IP = IPAddress.Parse(Settings1.IPAddress);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top