C# 从另一个项目的文件编译对roslyn的引用
我正在尝试使用roslyn动态构建一个程序集,稍后将从 ASP.NET核心“AddApplicationParts”扩展方法,在我的web应用程序的启动阶段 我正在从另一个项目外部加载一个.cs文件,它在那里工作得很好 下面是代码,我已经完成了所有工作,但我似乎无法确定如何从外部项目加载“引用”,我尝试了从metadatafile添加所谓的“引用”,但没有成功C# 从另一个项目的文件编译对roslyn的引用,c#,asp.net,.net,asp.net-core,roslyn,C#,Asp.net,.net,Asp.net Core,Roslyn,我正在尝试使用roslyn动态构建一个程序集,稍后将从 ASP.NET核心“AddApplicationParts”扩展方法,在我的web应用程序的启动阶段 我正在从另一个项目外部加载一个.cs文件,它在那里工作得很好 下面是代码,我已经完成了所有工作,但我似乎无法确定如何从外部项目加载“引用”,我尝试了从metadatafile添加所谓的“引用”,但没有成功 using System; using System.Collections.Generic; using System.IO; usi
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.AspNetCore.Hosting;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.Reflection;
using System.Collections.Immutable;
namespace WebApplication1
{
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.UseApplicationInsights()
.Build();
Pr2.Main2();
host.Run();
}
}
public class Pr2
{
public static void Main2()
{
string code = File.ReadAllText(@"c:\users\victor\documents\visual studio 2017\Projects\WebApplication2\WebApplication2\Controllers\HomeController.cs");
SyntaxTree tree = SyntaxFactory.ParseSyntaxTree(code);
CSharpCompilation compilation = CreateCompilation(tree);
SemanticModel model = compilation.GetSemanticModel(tree);
ShowLocalDeclarations(tree, model);
ShowDiagnostics(compilation);
ExecuteCode(compilation);
}
private static void ShowLocalDeclarations(SyntaxTree tree, SemanticModel model)
{
IEnumerable<LocalDeclarationStatementSyntax> locals = tree.GetRoot()
.DescendantNodes()
.OfType<LocalDeclarationStatementSyntax>();
foreach (var node in locals)
{
Microsoft.CodeAnalysis.TypeInfo type = model.GetTypeInfo(node.Declaration.Type);
Console.WriteLine("{0} {1}", type.Type, node.Declaration);
}
}
private static Assembly ExecuteCode(CSharpCompilation compilation)
{
Assembly roRet;
using (var stream = new MemoryStream())
{
compilation.Emit(stream);
roRet = Assembly.Load(stream.GetBuffer());
}
return roRet;
}
private static void ShowDiagnostics(CSharpCompilation compilation)
{
ImmutableArray<Diagnostic> diagnostics = compilation.GetDiagnostics();
foreach (var diagnostic in diagnostics)
{
// OVER HERE WE SEE THE ERRORS.
Console.WriteLine(diagnostic.ToString());
}
}
private static CSharpCompilation CreateCompilation(SyntaxTree tree)
{
CSharpCompilationOptions options = new CSharpCompilationOptions(
OutputKind.DynamicallyLinkedLibrary);
PortableExecutableReference reference = MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
CSharpCompilation compilation =
CSharpCompilation.Create("test")
.WithOptions(options)
.AddSyntaxTrees(tree)
.AddReferences(reference);
return compilation;
}
}
}
问题是编译文件时只引用了
mscorlib
,但需要引用文件所依赖的所有程序集。您可以尝试一次完成一个装配,但我认为更好的选择是利用您有第二个csproj的事实,它包含您需要的所有信息。你只需要从那里获取信息
为此,可以使用MSBuild。请参考Microsoft.Build
和Microsoft.Build.Tasks.Core
软件包,然后使用此代码(改编自):
private静态IEnumerable GetReferences(字符串项目文件名)
{
var projectInstance=新的projectInstance(projectFileName);
var result=BuildManager.DefaultBuildManager.Build(
新建BuildParameters(),
新建BuildRequestData(projectInstance,新建[]
{
“ResolveProjectReferences”,
“ResolveAssemblyReferences”
}));
IEnumerable GetResultItems(字符串targetName)
{
var buildResult=result.ResultsByTarget[targetName];
var buildResultItems=buildResult.Items;
返回buildResultItems.Select(item=>item.ItemSpec);
}
返回GetResultItems(“ResolveProjectReferences”)
.Concat(GetResultItems(“ResolveAssemblyReferences”);
}
//在缅因州2
var references=GetReferences(@“C:\code\tmp\roslyn references\WebApplication2\WebApplication2.csproj”);
csharpcomilation=CreateCompilation(树,引用);
//在CreateComployment中
csharp编译=
csharpcomilation.Create(“测试”)
.带选项(选项)
.AddSyntaxTrees(树)
.AddReferences(references.Select(path=>MetadataReference.CreateFromFile(path));
您会遇到哪些错误?您需要添加更多引用。当我尝试将csproj的路径传递到新ProjectInstance(projectFileName)时,我遇到“system.io file not found”异常;
using Microsoft.AspNetCore.Mvc;
namespace WebApplication2.Controllers
{
public class TestController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult About()
{
ViewData["Message"] = "Your application description page.";
return View();
}
public IActionResult Contact()
{
ViewData["Message"] = "Your contact page.";
return View();
}
public IActionResult Error()
{
return View();
}
}
}
private static IEnumerable<string> GetReferences(string projectFileName)
{
var projectInstance = new ProjectInstance(projectFileName);
var result = BuildManager.DefaultBuildManager.Build(
new BuildParameters(),
new BuildRequestData(projectInstance, new[]
{
"ResolveProjectReferences",
"ResolveAssemblyReferences"
}));
IEnumerable<string> GetResultItems(string targetName)
{
var buildResult = result.ResultsByTarget[targetName];
var buildResultItems = buildResult.Items;
return buildResultItems.Select(item => item.ItemSpec);
}
return GetResultItems("ResolveProjectReferences")
.Concat(GetResultItems("ResolveAssemblyReferences"));
}
// in Main2
var references = GetReferences(@"C:\code\tmp\roslyn references\WebApplication2\WebApplication2.csproj");
CSharpCompilation compilation = CreateCompilation(tree, references);
// in CreateCompilation
CSharpCompilation compilation =
CSharpCompilation.Create("test")
.WithOptions(options)
.AddSyntaxTrees(tree)
.AddReferences(references.Select(path => MetadataReference.CreateFromFile(path)));