2012-07-31 8 views
5

Gibt es eine Möglichkeit, eine TXT-Datei als eine Klasse zu laden, von der mein Hauptprogramm dann Funktionen aufrufen kann? Ich versuche im Grunde, Mod-Unterstützung zu meiner einfachen App hinzuzufügen, wo der Benutzer Optionen aus jeder Datei auswählen kann. Die Datei folgt einem ähnlichen (aber nicht demselben) Format mit einer Reihe von Leerstellen (Funktionen), die im Hauptprogramm aufgerufen werden.C# - Laden Sie eine Textdatei als Klasse

Wie kann ich das tun? Ist das überhaupt möglich (wahrscheinlich nicht, um meine eigene Frage zu beantworten?), Wenn man bedenkt, dass es nicht zusammen mit dem Rest des Programms kompiliert werden würde?

Danke!

+0

Es ist möglich, aber Sie müssen den C# -Compiler aufrufen .. nicht-trivial. Einfacher, dass deine Mods in dlls kompiliert werden müssen, die du dann mit Reflektion laden und aufrufen kannst. – Blorgbeard

+0

Wahrscheinlich müssen Sie mit Roslyn suchen – Prescott

Antwort

6

Sehen Sie mich auf diese Frage zu beantworten: Compile a C# Array at runtime and use it in code?

Im Wesentlichen würden Sie Ihre Textdatei in das CodeDom ziehen wollen und kompilieren. Danach wäre es wahrscheinlich hilfreich, ein paar dynamische Methoden als Ausführungshelfer zu erstellen.

  • Erhalten uploaded Datei
  • Führen Sie alle benötigte Validierung auf die Datei
  • Lesen Sie die Datei als String in den CodeDom
  • Deal mit jedem Compiler/Strukturfehler
  • erstellen Hilfsmethoden mithilfe von Linq Ausdruck Bäume oder dynamische Methoden, so dass die Verknüpfung zwischen der neuen Klasse und dem vorhandenen Code mit einem kompilierten Objekt überbrückt wird (andernfalls müssten alle neuen Methoden mittels Reflektion aufgerufen werden)

var csc = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v4.0" } }); 
var cp = new CompilerParameters() { 
    GenerateExecutable = false, 
    OutputAssembly = outputAssemblyName, 
    GenerateInMemory = true 
}; 

cp.ReferencedAssemblies.Add("mscorlib.dll"); 
cp.ReferencedAssemblies.Add("System.dll"); 

StringBuilder sb = new StringBuilder(); 

// The string can contain any valid c# code 

sb.Append("namespace Foo{"); 
sb.Append("using System;"); 
sb.Append("public static class MyClass{"); 
sb.Append("}}"); 

// "results" will usually contain very detailed error messages 
var results = csc.CompileAssemblyFromSource(cp, sb.ToString()); 

Auch finden Sie in diesem Thema: Implementing a scripting language in C#. IronPython mit dem DLR könnte für Ihre Bedürfnisse geeignet sein.

+0

Das ist die Sache - ich will es nicht unbedingt kompilieren, ich brauche es nur als Skript auszuführen. – Scott

+1

Ich verstehe. Zu Ihrer Information, Skripte sind auch kompiliert, nur im laufenden Betrieb. Abhängig von Ihren Leistungsanforderungen kann eine dynamische Kompilierung geeignet sein, obwohl die C# -Kompilierung wahrscheinlich für On-the-Fly-Vorgänge weniger optimiert ist. –

+0

Das sieht wirklich toll aus, ich füge es hinzu! Vielen Dank! – Scott

1

ein Framework verwenden, die Plugins Griffe

Der Managed Extensibility Framework ist genau das, was Sie suchen

http://mef.codeplex.com/

Der Managed Extensibility Framework (MEF) ist eine Zusammensetzungsschicht für .NET, das die Flexibilität, Wartbarkeit und Testbarkeit großer Anwendungen verbessert. MEF kann für die Plugin-Erweiterbarkeit von Drittanbietern verwendet werden, oder es kann die Vorteile einer lose gekoppelten pluginartigen Architektur für reguläre Anwendungen nutzen.

Das MEF bietet eine wohldefinierte Architektur zur Unterstützung von Plugins in Ihrer Anwendung.

DLL vs. Text (Source Code)

Der Plugin-Entwickler wird erwartet, dass eine DLL, um den Plugin-Code enthält. Bei Bedarf können Sie jedoch mithilfe von Roslyn Quellcode in eine DLL für sie kompilieren. Beachten Sie, dass Sie, wenn Sie den Quellcode des Plugins erhalten möchten, auch Unterstützung bereitstellen müssen, um dem Benutzer zu helfen, mit Compilerfehlern umzugehen und das Plugin in Ihrem Framework zu debuggen. Es kann klüger sein, sie zu verlangen, eine DLL zur Verfügung zu stellen.

+1

Würde dies mit einer TXT-Datei als eine Klasse arbeiten? Ich würde denken, er müsste es im Wesentlichen kompilieren – Prescott

+0

@ Prescott: Meine Antwort aktualisiert, um diesen Punkt zu adressieren. –

+0

Irgendwelche Updates diesbezüglich? –

3

Sie könnten eine Textdatei laden und dann einige Compiler-as-a-Service (entweder Microsoft's pre-release Roslyn project oder) verwenden. Dann können Sie die kompilierten Ausgaben nehmen und sie in Ihrem Programm ausführen.

Wenn es möglich ist, dass Ihr Benutzer Ihnen eine kompilierte Assembly anstelle einer unkompilierten Quelldatei zur Verfügung stellt, sollten Sie die Managed Extensibility Framework oder Mono.Addins berücksichtigen. Der zweite Ansatz (Erweiterungsbaugruppen) scheint mir aus mindestens zwei Gründen besser zu sein: 1) Ihr Benutzer kann jede Entwicklungsumgebung verwenden, um sicherzustellen, dass der Code korrekt kompiliert wird, bevor er sie an Sie übergibt, und 2) Sie haben weniger zu tun, um Eingaben zu validieren und Fehler zu behandeln.

+0

Danke! Ich schaue mir Roslyn an, da gibt es ein paar Kommentare darüber. – Scott

+2

Unterschätzen Sie nicht Mono.CSharp - es ist ein "fertiges Produkt" dessen Schnittstelle Sie nicht ändern können. Roslyns Interface wird sich höchstwahrscheinlich zwischen dem aktuellen CTP-Zustand und seinem endgültigen RTM ändern. Sobald es näher am Versand ist, könnte Roslyn eine geeignetere Wahl für ein typisches .NET-Projekt sein, aber denken Sie daran, dass Mono-Assemblies genauso gut mit Microsoft CLR funktionieren wie alle anderen Assemblies. – sblom

Verwandte Themen