lima-city: Webhosting, Domains und Cloud
1 Pluspunkt 0 Minuspunkte

Ich habe eine Klasse, die ganz normal kompiliert im Projekt liegt. Jetzt würde ich gerne C# Code aus einer externen Datei (z. B. einer .cs oder .txt Datei) einlesen, zur Laufzeit kompilieren und dieser Code soll dann die vorhandene - bereits kompilierte - Klasse erweitern oder von ihr erben.

Laut diesem Blog ist das mit dem Paket Microsoft.CodeAnalysis.CSharp technisch machbar, wie würde man das in der Praxis umsetzen?

von  

1 Antwort

0 Pluspunkte 0 Minuspunkte

Das kannst du z.B mit Roslyn. Erstelle ein neues C# Projekt und füge eine Referenz zum Paket Microsoft.CodeAnalysis.CSharp hinzu.

using System.Reflection;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

public interface IPlugin
{
    void Execute();
}

class Program
{
    static async Task Main()
    {

        string code = await File.ReadAllTextAsync("Plugin.cs");
        var syntaxTree = CSharpSyntaxTree.ParseText(code);
        var references = AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic && !string.IsNullOrWhiteSpace(a.Location)).Select(a => MetadataReference.CreateFromFile(a.Location)).Cast<MetadataReference>();
        var compilation = CSharpCompilation.Create("DynamicAssembly", new[] { syntaxTree }, references, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

        using var ms = new MemoryStream();
        var result = compilation.Emit(ms);

        if (!result.Success)
        {
            foreach (var diagnostic in result.Diagnostics)
                Console.WriteLine(diagnostic);
            return;
        }

        ms.Seek(0, SeekOrigin.Begin);
        var assembly = Assembly.Load(ms.ToArray());
        var type = assembly.GetTypes().FirstOrDefault(t => typeof(IPlugin).IsAssignableFrom(t));
        if (type != null)
        {
            var plugin = (IPlugin)Activator.CreateInstance(type);
            plugin.Execute();
        }
    }
}

In den Ordner, in dem das kompilierte Programm (die Exe Datei) liegt, legst du die Datei Plugin.cs.

public class HelloPlugin : IPlugin
{
    public void Execute()
    {
        System.Console.WriteLine("Hello world from dynamic plugin!");
    }
}

Wenn du die Exe Datei ausführst sollte "Hello world from dynamic plugin!" ausgegeben werden.

von (709 Punkte)  
Diese Community basiert auf dem Prinzip der Selbstregulierung. Beiträge werden von Nutzern erstellt, bewertet und verbessert – ganz ohne zentrale Moderation.

Wer hilfreiche Fragen stellt oder gute Antworten gibt, sammelt Punkte. Mit steigender Punktzahl erhalten Mitglieder automatisch mehr Rechte, zum Beispiel

  • Kommentare verfassen
  • Beiträge bewerten
  • Inhalte bearbeiten
  • Inhalte ausblenden

So entsteht eine Plattform, auf der sich Qualität durchsetzt – getragen von einer engagierten Gemeinschaft. Unser Ziel: Guter Inhalt. Für alle.

2.3k Fragen

2.8k Antworten

253 Kommentare

11 Nutzer