Zum Inhalt springen

C# DLLzur Laufzeit einbinden


McSaesch

Empfohlene Beiträge

Servus,

ich muss abhängig vom System (32 oder 64 bit) eine unterschiedliche DLL verwenden. Folgender Aufbau: ich habe eine Wrapperklasse (Name: SqliteToCSharp), diese muss abhängig vom System entweder die 32 oder 64 bit Dll einbinden. Die Prüfung welches System vorliegt ist ganz simpel. intPtr.Size == 8 heißt 64 bit. Wie kann ich nun zur Laufzeit entscheiden welche Dll ich einbinden muss? DllImport funktioniert nur halb, da ich auch Instanzmethoden verwende. Hat jemand eine Idee??

Ich kriegs leider nicht hin...

Link zu diesem Kommentar
Auf anderen Seiten teilen

Servus,

ich muss abhängig vom System (32 oder 64 bit) eine unterschiedliche DLL verwenden. Folgender Aufbau: ich habe eine Wrapperklasse (Name: SqliteToCSharp), diese muss abhängig vom System entweder die 32 oder 64 bit Dll einbinden. Die Prüfung welches System vorliegt ist ganz simpel. intPtr.Size == 8 heißt 64 bit. Wie kann ich nun zur Laufzeit entscheiden welche Dll ich einbinden muss? DllImport funktioniert nur halb, da ich auch Instanzmethoden verwende. Hat jemand eine Idee??

Ich kriegs leider nicht hin...

Eine Möglichkeit wäre Dependency Injection. Frameworks wären u.a. hier:

Unity, Windsor Castle, Spring.NET

Link zu diesem Kommentar
Auf anderen Seiten teilen

Thx für die Hinweise, bin nun soweit gekommen

InitializeComponent();

Assembly currentAssembly;

string classNameSQLiteConnection = "System.Data.SQLite.SQLiteConnection";

string classNameSQLiteCommand = "System.Data.SQLite.SQLiteCommand";

if (IntPtr.Size == 8) //64 bit System

currentAssembly = Assembly.LoadFile(applicationPath.DirectoryName+ path64Bit);

else

currentAssembly = Assembly.LoadFile(applicationPath.DirectoryName + path32Bit);

object objConnection = currentAssembly.CreateInstance(classNameSQLiteConnection);

object objCommand = currentAssembly.CreateInstance(classNameSQLiteCommand);

Allerding nun die Frage, wie kann ich mir nun Instanzen der Klasse SQLiteConnection und SQLiteCommand erstellen?? Das kriege ich einfach nicht hin, da die Klassen nicht als Verweis eingebunden sind, und somit unbekannt. Kann ich sowas dynamisch überhaupt machen???

Link zu diesem Kommentar
Auf anderen Seiten teilen

Willkommen in der Dll-Hell :P

Das was Du da versuchst nennt sich dynamische bzw. späte Bindung. Dabei ist der Ansatz, dass Du mit der "System.Reflection" Bibliothek Objekte erzeugst deren Typ dann mit der von "object" geerbten Methode "getType()" ermittelst und dann z.B. mit der Methode "InvokeMember(...)" der Klasse Type Methoden oder Properties aus der dynamisch erzeugten Instanz der ermittelten Klasse aufrufst.

Hört sich kompliziert und umständlich an.

zu kompliziert: Nein

zu umständlich: Auf jeden Fall

jetzt mal Butter bei die Fisch:


Assembly currentAssembly;


            string classNameSQLiteConnection = "System.Data.SQLite.SQLiteConnection";

            string classNameSQLiteCommand = "System.Data.SQLite.SQLiteCommand";


            if (IntPtr.Size == 8) //64 bit System

            currentAssembly = Assembly.LoadFile("");

            else

            currentAssembly = Assembly.LoadFile("");


            object objConnection = currentAssembly.CreateInstance(classNameSQLiteConnection);

            object objCommand = currentAssembly.CreateInstance(classNameSQLiteCommand);

            // Beispiel MethodenAufruf objConnection

            Type connType = objConnection.GetType();

            int irgendeinParameter = 7;

            String nochirgendeinParameter = ";)";

            connType.InvokeMember("gesuchterMethodenName", BindingFlags.InvokeMethod, null, objConnection, new object[] {irgendeinParameter ,  nochirgendeinParameter}); 

            // Beispiel Get-Propertie objCommand

            Type comType = objCommand.GetType();


            String conString = (String)connType.InvokeMember("ConnectionString", BindingFlags.GetProperty, null, objCommand, new object[] { });

Solang du Keine (abstrakte) Oberklasse zu den in Frage kommenden Konkreten Instanzen von bsp. "System.Data.SQLite.SQLiteConnection" hast, die auch noch alle benötigen Methoden (abstrakt) deffiniert hat, kannst du nicht Casten. Wenn du eine Solche Klasse hast gehts auch so.

....

AbstrakterTyp oberklasse = (AbstrakterTyp)objCommand ;

String conString = oberklasse.ConnectionString;

Bearbeitet von Mcolli
Link zu diesem Kommentar
Auf anderen Seiten teilen

Solang du Keine (abstrakte) Oberklasse zu den in Frage kommenden Konkreten Instanzen von bsp. "System.Data.SQLite.SQLiteConnection" hast, die auch noch alle benötigen Methoden (abstrakt) deffiniert hat, kannst du nicht Casten. Wenn du eine Solche Klasse hast gehts auch so.

Muss nicht mal eine Klasse sein. Interface reicht.

(Contract-First-Design-Pattern)

Mal davon abgesehen "SQLiteConnection" und "SQLiteCommand" sind bestimmt von DbConnection bzw. DbCommand abgeleitet.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Muss nicht mal eine Klasse sein. Interface reicht.

(Contract-First-Design-Pattern)

Haste natürlich Recht. Wobei Interface in C# im verglecih zu Java schon an bedeutung verliert da man von mehreren Klassen erben kann...

@ Topic nochmal

Ich hab noch mal nachgedacht und als Ergänzung ist mir eingefallen, dass Du Dich evtl mal der Microsoft Biliothek "Enterprise Library" anfreunden könntest. Unteranderm hat diese eine sogenannten Data Application Block der sich mit der Abstraktion von Datenbank Zugriffen beschäft.

Ich hab vor ca. 6 Monaten angefangen damit zu arbeiten und die Enterprise Library ist ein wundervolles Werkzeug um mit unterschiedlichen Datenquellen syntaktisch glecihbleibend zu Arbeiten. Und das beste: Es ist alles Idiotensicher. Typches Snippet wäre:

// "meineQuelle" ist in der Appconfig hinterlegbar und bildet einen

// ConnectionString

Database db = DatabaseFactory.CreateDatabase("meineQuelle");

using (IDataReader reader = db.ExecuteReader(CommandTye.Text, "Select o.Wissen From table_mcolli)) {

while (reader.Read())

{

// Blabla

}

}

Kannst auch DataSet Abfragen als DataContext angeben und soweiter.

WICHTIG nur: bei dem ConnectionString in der App.config das Attribut pooling=false setzen. Wenn Du Passwort Attribute setzt kannst DU das auch mit dem Cryptodingsbums Applicationblock chiffrieren.

Auf unserer Oracle 10g Datenbank hatte ich bei einer eigenen Multithreaded Anwendung vorher >40 Sessions auf :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

@Mcolli

Haste natürlich Recht. Wobei Interface in C# im verglecih zu Java schon an bedeutung verliert da man von mehreren Klassen erben kann...

Das verstehe ich nicht ganz. Meines Wissens gibt es in C# keine Mehrfachvererbung.

Mal schnell google angeworfen und Microsoft behauptet das gleiche:

Vererbung und abgeleitete Klassen (C# und Java im Vergleich)

Bearbeitet von Pointerman
Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...