Laden...

Mit .NET Core und Roslyn erstellte dll wirft "The type 'Object' is defined..." Fehler in anderer dll

Erstellt von Quaneu vor 3 Jahren Letzter Beitrag vor 3 Jahren 2.000 Views
Quaneu Themenstarter:in
692 Beiträge seit 2008
vor 3 Jahren
Mit .NET Core und Roslyn erstellte dll wirft "The type 'Object' is defined..." Fehler in anderer dll

Hallo zusammen,

ich habe mit Roslyn eine dll in einem .Net Core 3.1 Projekt generiert. Dazu erstelle ich eine CSharpCompilation Instanz und rufe auf ihr Emit(...) auf. Dies klappt alles und das EmitResult hat keine Fehler.

Folgende Referenzen benutze ich in dieser dll.


var coreDir = Path.GetDirectoryName(typeof(object).GetTypeInfo().Assembly.Location);
MetadataReference[] reference =
{
	MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Private.CoreLib.dll")),
	MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Private.Xml.dll")),
	MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Private.Uri.dll")),
	MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Runtime.dll")),
	MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Runtime.Extensions.dll")),
	MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Xml.ReaderWriter.dll")),
	MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Text.RegularExpressions.dll"))
};

Wenn ich nun die erstellte dll in meinem Test (auch eine .Net Core 3.1 Projekt) einbinde, bekomme ich folgende Fehler, für Code aus dieser dll.

Fehlermeldung:
Error CS0012 The type 'Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'.
Error CS0012 The type 'Stream' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'.

Ich verstehe nicht was ich falsch mache. Mein Ziel ist es, das die dll auch ein .Net Core oder .Net Standard Projekt ist. Leider habe ich dazu keine Einstellungen gefunden, bzw. gelesen das der Output anscheinend imme ein .Net Standard Projekt sein soll. Wenn ich jedoch im Assembly Explorer die dll anschaue steht dabei, "... (x64, .Net Framework v4.7.2, Debug).

Ich hoffe mir kann wer einen Hinweis geben, was ich falsch mache bzw. vergessen habe.

Schöne Grüße
Quaneu

16.806 Beiträge seit 2008
vor 3 Jahren

HMein Ziel ist es, das die dll auch ein .Net Core oder .Net Standard Projekt ist.

Hä, warum? So geschrieben macht das wenig sinn.

Du kannst doch problemlos aus .NET Core eine .NET Standard Assembly referenzieren.
Der Mehrwert das auf .NET Core ebenfalls zu projizieren macht ja wenig sinn.

Quaneu Themenstarter:in
692 Beiträge seit 2008
vor 3 Jahren

Was meinst Du mit so geschrieben?

Also es darf auch gern .NET Standard sein. Aber beim erstellen der dll, kann ich dies nicht angeben, bzw. habe ich bisher nichts gefunden.

Aber wie geschrieben klappt dies nicht. Die generierte dll lässt sich einbinden, aber ich bekomme immer die Fehler aus meinem ersten Post.

Edit:
Noch mal als Information:
Ich habe ein .Net Core 3.1 Projekt, dass Code generieren soll, bzw. eine dll. Die dll die generiert wurde, binde ich in einen Testprojekt ein, das auch ein .Net Core 3.1 Projekt ist. Sobald ich Code aus der generierten dll verwenden will, zeigt mir VS die besagten Fehler an.

Quaneu Themenstarter:in
692 Beiträge seit 2008
vor 3 Jahren

Update:

Selbst wenn ich die generierte dll in ein .Net Standard Projekt einbinde, bekomme ich die Fehler. Ich denke beim bauen der dll geht etwas schief. bzw. mache ich ein Fehler. Aber leider sehe ich den Fehler nicht...

4.930 Beiträge seit 2008
vor 3 Jahren

Wie rufst du den Roslyn-Compiler denn auf (mit EmitOptions.EmitMetadataOnly)?
Dann werden dort nur Verweisassemblies benutzt (s.a. Generieren von Verweisassemblys).
Und du mußt dann im Hauptprojekt eben die Implementierungs-Assemblies als Verweis (Referenz) angeben.

Edit: Unter Runtime code generation using Roslyn compilations in .NET Core App gibt es weiter Infos dazu.

Quaneu Themenstarter:in
692 Beiträge seit 2008
vor 3 Jahren

Ich habe es bisher mit Emit(Stream) aufgerufen. Auch wenn ich es mit den Deinem Vorschlag probiere klappt es leider nicht.

Wenn ich selbst eine .Net Core dll erstelle und in einem anderen Projekt einbinde, muss ich auch nicht die "System.Private.CoreLib" dlls usw. einbinden.
Ich hatte in meinem ersten Beitrag auch erwähnt, dass der Assembly Explorer für die generierte dll .Net Framework anzeigt, was mirfalsch vorkommt. Wenn ich eine .Net Core dll anschaue bekomme ich das nicht. Ich habe mal ein Bild angefügt, damit man sehen kann, was ich meine. Aber ich weiß nicht warum er keine .Net Core dll generiert...

4.930 Beiträge seit 2008
vor 3 Jahren

Wie sieht denn dein CSharpCompilation-Code (inkl. CompilationOptions) aus?

Edit: Habe gerade Compiling and Executing Code in a C# App gefunden, welcher wohl anfangs den selben Fehler bekommen hat...

Quaneu Themenstarter:in
692 Beiträge seit 2008
vor 3 Jahren

Hier mein Code:


private static CSharpCompilation CreateCompileUnit(string dllName, NamespaceDeclarationSyntax namespaceDeclaration)
{
	CompilationUnitSyntax compileUnit = SyntaxHelper.BuildCompilationUnit(namespaceDeclaration);
	string sourceCodeAsText = compileUnit.NormalizeWhitespace("\t", Environment.NewLine).ToFullString();
	SyntaxTree tree = CSharpSyntaxTree.ParseText(sourceCodeAsText);
	SyntaxTree[] trees = { tree };
	CSharpCompilationOptions compilerOptions = new CSharpCompilationOptions(
		OutputKind.DynamicallyLinkedLibrary, optimizationLevel: OptimizationLevel.Debug, platform: Platform.X64);

	var coreDir = Path.GetDirectoryName(typeof(object).GetTypeInfo().Assembly.Location);
	MetadataReference[] reference =
	{
		MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Private.CoreLib.dll")),
		MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Private.Xml.dll")),
		MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Private.Uri.dll")),
		MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Runtime.dll")),
		MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Runtime.Extensions.dll")),
		MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Xml.ReaderWriter.dll")),
		MetadataReference.CreateFromFile(Path.Combine(coreDir, "System.Text.RegularExpressions.dll"))
	};
	CSharpCompilation compilation = CSharpCompilation.Create(dllName, trees, reference, compilerOptions);
	return compilation;
}

4.930 Beiträge seit 2008
vor 3 Jahren

Hatte zeitgleich gerade meinen letzten Beitrag editiert. Probiere mal dessen Code (mit der JSON-Datei).

Edit: In Compiling .NET Core App with Roslyn API wurde es ähnlich gelöst.

Quaneu Themenstarter:in
692 Beiträge seit 2008
vor 3 Jahren

Einen ähnlichen Artikel habe ich auch schon gefunden, aber diese Lösung bezieht sich wohl nur auf "Console Application" und nicht auf "Class Library". Aber ich kann es mal probieren.

Edit1:
Also habe jetzt mal die Datei neben die generierte dll geleget, aber leider bringt das auch nichts.

Edit2:
Bild aus ILSpy.

Quaneu Themenstarter:in
692 Beiträge seit 2008
vor 3 Jahren

Update:
Ich konnte die Fehler jetzt "lösen", bzw. kommen sie nicht mehr. Aber leider zeigt mir der AssemblyResolver trotzdem noch .Net Framework an 😦

Auf github habe ich die Lösung gefunden. Also wenn ich auf dem "refs" Ordner nur noch die ""netstandard.dll" kommen keine Fehler mehr. Bleibt noch das ".Net Framework" Problem...