Laden...

Aufteilen eines Projektes in Module

Erstellt von weismat vor 18 Jahren Letzter Beitrag vor 18 Jahren 5.033 Views
W
weismat Themenstarter:in
872 Beiträge seit 2005
vor 18 Jahren
Aufteilen eines Projektes in Module

Ich habe eine Klassenbibliothek mit Hilfsklassen geschrieben. Wie kann ich diese Hilfsklasse so einsetzen, daß ich in verschiedenen Programmen die gleichen Klassen einsetzen kann. Ich benutze Visual Studio 2005 Beta 2.
Ich habe sowohl in dem Tutorial aus dem Forum als auch in Programmieren in C+ von Jesse Liberty geschaut und nichts gefunden.
Danke!

4.221 Beiträge seit 2005
vor 18 Jahren

Lagere die Klassen in ein DLL aus...

Dieses kannst Du dann in allen Projekten referenzieren.

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

-
885 Beiträge seit 2004
vor 18 Jahren

Da ich etwa das gleiche Problem habe und keinen neuen Thread aufmachen wollte, schreibe ich mal hier.

Ich habe eine Hauptanwendung (exe). Zudem ewig viele Module[DLLs] (Controls & Componenten) für diese Anwendung geschrieben und möchte gerne folgende Struktur haben:

Root:
EXE-File
Ordner Libs
Componente A (DLL)
Componente B (DLL)
...

Das hat den Sinn, dass mein Programm nicht jedes mal neu kompiliert werden muss, wenn eine DLL aktualisiert wurde. So brauche ich nur die DLL austauschen bei einem Update.

Jetzt meine eigentliche Frage: Wenn ich den Ordner Root (C:...Debug) verschiebe, stimmt ja eigentlich nicht mehr der Pfad zu den DLLs oder wird dieser dynamisch angepasst? Ist dieses Verfahren gut oder habt ihr Verbesserungsvorschläge? Achja LocalCopy lasse ich dann auf false, ne?

S
8.746 Beiträge seit 2005
vor 18 Jahren

Die Art und Weise wie Assemblies zur Laufzeit aufgefunden werden ist in .NET recht ausgefuchst. Guckst du hier:

dll abhängigkeiten

Prinzipiell funktioniert das Verschieben des Root-Verzeichnisses. Die festen Pfade, die du zur Design-Zeit für Referenzen angibst, werden zur Laufzeit nicht mehr benötigt sondern die Module dynamisch gesucht.

-
885 Beiträge seit 2004
vor 18 Jahren

Also bei mir funktionierts nur, wenn die DLLs im Debugverzeichnis selbst liegen.
Mach ich aber ein Unterverzeichnis gehts nicht. Was habe ich vergessen?

Edit: Hab gerade mal einen ReferencePath gesetzt in den Projekteigenschaften. Jetzt stimmt der Pfad zur DLL wenn ich auf eigenschaften gehe. Im Desinger kann ich jetzt mit arbeiten, aber wenn ich kompiliere, findet er wieder das Control nicht...

S
8.746 Beiträge seit 2005
vor 18 Jahren

Lies dir nochmal genau den englischen Text im verwiesenen Posting durch. Du kannst das auch in der MS-Hilfe nachlesen.

Und auch mein letztes Posting hier solltest du nochmal aufmerksam lesen:

"Die festen Pfade, die du zur Design-Zeit für Referenzen angibst, werden zur Laufzeit nicht mehr benötigt sondern die Module dynamisch gesucht."

Dein Control wird nicht gefunden, weil es nicht im .NET-Suchpfad deiner Anwendung ist. Die Designer-Referenzen haben damit nix zu tun. Normalerweise wird aber bei Referenzen auf Assemblies, die nicht im GAC sind, die referenzierte DLL mit in den Ausführungsordner (also Debug) kopiert (es sei denn du machst in den Referenz-Eigenschaften "Lokale Kopie" auf false). Es wird also nicht direkt die referenzierte Assembly genutzt, sondern eine Kopie im Anwendungsordner.

-
885 Beiträge seit 2004
vor 18 Jahren

Dynamisch suchen hin oder her - es geht nicht!

Anfangs hatte ich ja auch verschiedene Verzeichnisse gehabt:

Controls

  • Panel
  • Menu
    Hauptprojekt
  • Exe
    ...

Es hat alles funktioniert und er hat auch die DLL in den Debugordner kopiert. Verschiebe ich aber eine eingebundene DLL (aus Controls zb. Panel) geht es nicht mehr! Leider werde ich aus dem englischen Text nicht wirklich schlau. Es wäre super, wenn du mir weiterhilfst.

S
8.746 Beiträge seit 2005
vor 18 Jahren

Hier nochmal ein Link für eine Beschreibung in Deutsch (ab Seite 8).

http://www.ssw.uni-linz.ac.at/Teaching/Lectures/Sem/2003/reports/Steinbacher/Steinbacher.pdf

S
8.746 Beiträge seit 2005
vor 18 Jahren

Hier nochmal ein Link für eine Beschreibung in Deutsch (ab Seite 8 ).

http://www.ssw.uni-linz.ac.at/Teaching/Lectures/Sem/2003/reports/Steinbacher/Steinbacher.pdf

Und noch eine Zusammenfassung (http://www.entwickler-forum.de/webx?50@214.ttcmabsxdvf.0@.2cb7e309):

"Das Laden einer Assembly lässt sich in verschiedene Arbeitsschritte unterteilen. Zuerst such die CLR nach einer anwendungsspezifischen Konfigurations-Datei mit der Dateiendung .config. Wird dies gefunden, sucht die CLR dort nach Einträgen, die den Ladevorgang beeinflussen – wie zum Beispiel CodeBase oder privatePath. Außerdem wird die Assembly auch im AppBase-Verzeichnis (also dem Installationsverzeichnis der aufrufenden Anwendung) gesucht. Nur dann, wenn die angeforderte DLL einen Strong Name besitzt, sucht die CLR auch im Global Assembly Cache (GAC). Ist auch dort keine passende Assembly aufzutreiben, berücksichtigt die CLR die vorgefundenen Versionsnummern-Policies, so dass ein "Umbiegen" auf andere Versionsnummern unterstützt wird.

Das Tool Assembly Binding Log Viewer (FUSLOGVW.EXE) protokolliert genau mit, wo die CLR überall nach dieser Assembly gesucht hat, bevor die Exception geworfen wurde. "

S
8.746 Beiträge seit 2005
vor 18 Jahren

Sorry für den Doppel-Post. Scheint sich um einen Bug im Zuge der 30-Sekunden-Sperre zu handeln.

-
885 Beiträge seit 2004
vor 18 Jahren

Ansich ne coole Sache. Im andren Beitrag schreibst du auf die Frage wo man den Path setzt:

This location can be specified in the application configuration file and in managed code using the AppendPrivatePath property for an application domain.

Wo finde ich denn dieses config-File?

1.373 Beiträge seit 2004
vor 18 Jahren

Selbst schreiben! Ihr name lautete namederexe.config, also für foobar.exe lautet sie foobar.exe.config. (BTW: Wenn du in Visual Studio eine app.config zum Projekt hinzufügst, übernimmt VS das Kopieren und Umbennen selbst).

Doku:
http://msdn.microsoft.com/library/en-us/cpgenref/html/gngrfNETFrameworkConfigurationFileSchema.asp

Du suchst: <configuration><runtime><assemblyBinding><probing>

Oh, und ich schieb es mal nach Rund um....

-
885 Beiträge seit 2004
vor 18 Jahren

Ah cool ja. Also wenn ich richtig gelesen habe, ist es einfach nur ein XML-Dokument, welches ich dann applicationname.exe.config nennen muss. Reicht es, wenn ich in meinem Projekt "Add" -> "New Item" -> "XML File" mache und dort den Code

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <probing privatePath="bin;bin\\Libs"/>
      </assemblyBinding>
   </runtime>
</configuration>

einfüge?

I
1.739 Beiträge seit 2005
vor 18 Jahren

"Add" -> "New Item" -> "Application configuration file"
geht auch. Nennt sich dann App.config und wird beim build autom. umbenannt.

-
885 Beiträge seit 2004
vor 18 Jahren

Wollte nur mal sagen, dass es super funzt. Danke an alle =)

-
885 Beiträge seit 2004
vor 18 Jahren

Aber ne kleine Frage bleibt doch noch:

Was ist wenn eine eingebundene dll ausgetauscht wurde (gegen eine neuere Version)? Bei mir kommt leider ein Fehler "...already been imported". Weil dafür sollte ja die Grundidee sein, damit ich per Update nur dlls austauschen muss, statt jedes mal die Exe mitzuschicken.

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo -acid-,

"...already been imported" klingt nach Assembly.Load. Wenn ich das richtig verstehe, würde dir aber statisches Linken reichen (also DLLs beim Compilieren Referenzieren).

Wenn du es wirklich mit Assembly.Load machst, sollte dir dlls freigeben helfen.

herbivore

4.506 Beiträge seit 2004
vor 18 Jahren

Hallo -acid-!

Wenn Du Visual Studio benutzt, kannst Du die Dll's auf 2 verschiedene Arten und Weisen eibinden, indem Du die DLL normal einbindest, dann beim Solution-Explorer auf die eingebundene DLL klickst und im Property Window die Einstellung "Copy Local" von "True" auf "False" setzt.

Das bewirkt, dass er die DLL nicht ins Projektverzeichnis kopiert, sondern immer von der angegebenen Stelle referenziert. Das heißt, dass bei einer Änderung der DLL alle Projektreferenzen auf einmal aktualisiert worden sind 😉

Nachdem Du Deine Software fertig entwickelt hast (im Speziellen Deine DLL) kannst Du die oben genannte Einstellung rückgängig machen und Dir die DLL dann ins Projektverzeichnis kopieren lassen...

Ciao
Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

-
885 Beiträge seit 2004
vor 18 Jahren

Also das mit true/false ist mir schon klar Nochmal zur meiner Situation:

Ich entwickle an meiner exe die eigentlich nie fertig wird. Genausowenig werden die meisten dlls auchn ie fertig werden. Daher soll die Ordnerstruktur sein:

Exe (Das ist Root)
libs (Ordner für Dlls)

Wenn der Enduser dann ein Update macht, brauchen nur teilweise die Module upgedatet zu werden, sprich einfach nur die Dlls ausgetauscht werden (im seltesten Fall die Exe).

Genau diese Struktur habe ich jetzt und füge aus "libs" die dlls ein. Übe ich allerdings den Ernstfall, dass eine dll eine neue Version hat und ins "libs" Verzeichnis kopiert wird, startet meine Exe nicht mehr. Wie soll ich da vorgehen? Und nochmals: Ich will nicht, dass die dlls im Root liegen...

S
8.746 Beiträge seit 2005
vor 18 Jahren
-
885 Beiträge seit 2004
vor 18 Jahren

svenson wirklich vielen Dank für deine Hilfe. Das Buch hat mich schon etwas weiter gebracht. Leider nicht zum Ziel.

Also ich habe das so verstanden, dass es KEINE Versionsunterschiede bei meinen Dlls gibt. Daher bringt er den Fehler. Ich benötige also nun den StrongName und irgendwas muss ich mit dieser sn.exe machen... aber mir fehlt noch der richtige Durchblick. Kannst du/könnt ihr mir weiterhelfen?

Ich habe meine App.config schonmal erweitert:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<runtime>
		<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
			<probing privatePath="libs"/>
			<bindingRedirect oldVersion="*" newVersion="*"/>
		</assemblyBinding>
	</runtime>
</configuration>
S
8.746 Beiträge seit 2005
vor 18 Jahren

Nochmal eine Idee: In einem der letzten Positing von mir wurde ein Tool erwähnt, mit dem man den Ladevorgang überwachen kann. Bitte besorge dir das und schmeisse hier mal den Output und die genau Fehlerrmeldung, zur Not als Screenshot hier rein. Solche Problem sind immer ziemlich knifflig und bedürfen einer absolut exakten Fehlerbeschreibung.