2017-01-10 2 views
3

В настоящее время я пишу приложение, которое в настоящее время загружает проект через API-интерфейс рабочей области Roslyn, превращает указанный файл C# в дерево синтаксиса, затем создает в нем сборку в форме памяти, а затем извлекает IL ,Автоматическое решение зависимостей при компиляции с использованием Roslyn

Все работает нормально, однако, как только я ссылаюсь на любые внешние библиотеки в указанном 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?) 

И файл мой проект Рослин читает это просто:

 
using MediatR; 

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

Мой вопрос в том, делает ли Roslyn API для автоматической загрузки любые зависимости, которые может иметь файл? Я надеялся, что рабочее пространство Roslyn позволит это сделать, но я ничего не смог найти.

+0

Вы уверены, что из-за невозможности загрузки ссылок, а не, например, некоторая синтаксическая ошибка? Покажите нам точную ошибку компилятора. –

+0

Я обновил свой вопрос, чтобы включить вывод ошибки и файл, который я читаю. –

+0

Итак, вы надеетесь, что директива 'using MediatR;' разрешит вашу библиотеку? Вот почему у вас есть # # 'в CSharpScript. Даже «MetadataReferences» необходимо устранить, см. [MetadataReferenceResolver] (http://source.roslyn.io/#Microsoft.CodeAnalysis/MetadataReference/MetadataReferenceResolver.cs,4d808b77e09b1008). Это единственный способ достичь этого, о котором я могу думать, - это скомпилировать # 1, # 2 проверить известные ошибки, попытаться добавить ссылки, goto # 1. Но даже это не будет работать для методов расширения и т. Д., Которые разделяют пространство имен ... – m0sa

ответ

1

Если проект консоли MediatR является проектом project.json, вы можете использовать ProjectJsonWorkspace от "Microsoft.DotNet.ProjectModel.Workspaces": "1.0.0-preview2-1-003177". Вы можете указать его на свой project.json и получить объект Compilation, это сделало бы всю тяжелую работу для вас, чтобы получить ссылки на проект, ссылки на файлы и т. Д. Затем вы можете просто испустить ваш ИЛ отсюда.

Вот пример:

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.

Надеюсь, что это поможет.

+1

Perfect, 'ProjectJsonWorkspace' именно то, что я искал, спасибо! –

Смежные вопросы