簡體   English   中英

使用Roslyn進行編譯時自動解析依賴關系

[英]Automatically resolving dependencies when compiling using Roslyn

我目前正在編寫一個當前通過Roslyn的工作空間API加載項目的應用程序,將指定的C#文件轉換為語法樹然后創建一個內存匯編形式,然后最終提取IL。

這一切都運行正常,但是當我引用所述C#文件中的任何外部庫時,編譯失敗,因為Roslyn不知道在哪里解析這些引用。

這是我目前正在做的簡化版本:

MetadataReference[] metaDatareferences = {
    MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location),
    MetadataReference.CreateFromFile(typeof(Uri).GetTypeInfo().Assembly.Location),
    MetadataReference.CreateFromFile(typeof(DynamicAttribute).GetTypeInfo().Assembly.Location),
    MetadataReference.CreateFromFile(typeof(AssemblyMetadata).GetTypeInfo().Assembly.Location),
};

var sourceLanguage = new CSharpLanguage();

var syntaxTree = sourceLanguage.ParseText(sourceCode, SourceCodeKind.Regular);
var options = new CSharpCompilationOptions(
    OutputKind.DynamicallyLinkedLibrary,
    optimizationLevel: OptimizationLevel.Debug,
    allowUnsafe: true
);

CSharpCompilation compilation = CSharpCompilation.Create("ExampleAssembly", options: options);

var stream = new MemoryStream();
var result = compilation.
    AddReferences(metaDatareferences)
    .AddSyntaxTrees(syntaxTree)
    .Emit(stream);

// Success is false
if (!emitResult.Success)
{
    foreach (var diagnostic in emitResult.Diagnostics)
    {
        Debug.WriteLine(diagnostic.ToString());
    }
}

Debug.WriteLine的輸出是:

(1,7): error CS0246: The type or namespace name 'MediatR' could not be found (are you missing a using directive or an assembly reference?)
(9,32): error CS0246: The type or namespace name 'Mediator' could not be found (are you missing a using directive or an assembly reference?)

我的Roslyn項目正在閱讀的文件就是這樣:

using MediatR;

namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var mediator = new Mediator(null, null);
        }
    }
}

我的問題是,Roslyn是否提供了一個API來自動加載文件可能具有的任何依賴項? 我希望Roslyn工作區能夠完成這項工作,但我找不到任何東西。

如果MediatR控制台項目是一個project.json項目,那么你可以使用ProjectJsonWorkspace"Microsoft.DotNet.ProjectModel.Workspaces": "1.0.0-preview2-1-003177" 你可以將它指向你的project.json並獲得一個Compilation對象,這將為你獲得項目引用,文件引用等所有艱苦的工作......然后你可以從這里發出你的IL。

這是一個例子:

var compilation = new ProjectJsonWorkspace(@"PathToYour\project.json").CurrentSolution.Projects.First().GetCompilationAsync().Result;

var stream = new MemoryStream();
var emitResult = compilation.Emit(stream);

或者,如果需要完全控制,可以繼續使用CSharpCompilation.Create ,在此處從compilation對象中復制所需內容,並傳入SyntaxTree

希望有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM