【问题标题】:References to roslyn compiled from file from another project对从另一个项目的文件编译的 roslyn 的引用
【发布时间】:2017-03-30 06:40:01
【问题描述】:

我正在尝试使用 roslyn 动态构建程序集,然后从 ASP.NET CORE 'AddApplicationParts' 扩展方法,在我的网络应用程序的启动阶段。

我正在从另一个项目外部加载一个 .cs 文件,它工作得很好。

这是代码,我得到了一切工作,但我似乎无法弄清楚如何从外部项目加载“引用”,我尝试了从元数据文件中所谓的“添加引用”,但没有运气。

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;
        }
    }
}

外部文件位于另一个 asp.net 核心项目中,从 vs2017 核心模板开始,使用 4.6.2 框架。 !!

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();
        }
    }
}

【问题讨论】:

  • 您遇到什么错误?您需要添加更多参考资料。

标签: c# asp.net .net asp.net-core roslyn


【解决方案1】:

问题是您在编译文件时仅引用mscorlib,但您需要引用该文件所依赖的所有程序集。您可以尝试一次完成一个组装,但我认为更好的选择是利用您拥有第二个 csproj 的事实,其中包含您需要的所有信息。您只需要以某种方式从那里获取信息。

为此,您可以使用 MSBuild。引用Microsoft.BuildMicrosoft.Build.Tasks.Core 包,然后使用此代码(改编自this answer):

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)));

【讨论】:

  • 当我尝试将 csproj 的路径传递给新的 ProjectInstance(projectFileName); 时,我得到一个 'system.io file not found 异常;
猜你喜欢
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-29
  • 2013-11-08
  • 1970-01-01
  • 2017-02-09
  • 1970-01-01
相关资源
最近更新 更多