当前位置:  开发笔记 > 编程语言 > 正文

没有frameworkAssemblies,无法解决程序集引用问题

如何解决《没有frameworkAssemblies,无法解决程序集引用问题》经验,为你挑选了3个好方法。

我正在尝试验证Protocol Buffers是否适用于ASP.NET团队的新移植运行时,以及大多数其他现代环境.3.0.0-alpha4版本是前一段时间使用profile259创建的,所以我希望在某些情况下需要进行一些更改,但我想我会尝试一下.我知道Oren Novotny关于针对.NET Core的帖子,并且预计必须对Google.Protobuf nuspec文件进行一些更改,但是我遇到的错误让我感到难过.

DNX版本:1.0.0-rc1-update1

我目前正在尝试测试的方案是一个针对dnx451的控制台应用.我有一个非常简单的示例应用程序:

using Google.Protobuf.WellKnownTypes;
using System;

public class Program
{
    public static void Main(string[] args)
    {
        Duration duration = new Duration { Seconds = 100, Nanos = 5555 };
        Console.WriteLine(duration);
    }
}

......还有一点点project.json:

{
  "compilationOptions": { "emitEntryPoint": true },
  "dependencies": { "Google.Protobuf": "3.0.0-alpha4" },

  "frameworks": {
    "dnx451": { }
  }
}

请注意,我还没有使用dnxcore*在这里-讽刺的是,我在没有问题的工作.

dnu restore工作良好; dnx run失败了:

错误:c:\ Users\Jon\Test\Projects\protobuf-coreclr\src\ProtobufTest\Program.cs(9,9):DNX,Version = v4.5.1 error CS0012:类型'Object'在程序集中定义没有引用.您必须添加对程序集'System.Runtime,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a'的引用.

以下更改会导致相同的错误:

在框架"System.Runtime": "4.0.0"dependencies部分中明确添加依赖项

明确地添加依赖于"System.Runtime": "4.0.0-beta-23109"dependencies该框架部,并且同样地用于4.0.10-beta-*,4.0.20-beta-*4.0.21-beta*.

System.Runtime在NuGet包中添加依赖项(本地)并对其进行重建 - project.lock.json已更新为包含System.Runtime v4.0.0,但发生了相同的错误

同上,包括包中的lib\dotnet目录,以及依赖项

的步骤,工作(独立,并没有dependencies条目),但让我困惑:

Console.WriteLine呼叫更改为just Console.WriteLine("foo")(但没有其他更改)

duration变量的类型更改为object而不是Duration

完全删除所有协议缓冲区的提示,而不是使用TimeSpan或类似

在以下dnx451部分中将以下内容添加到project.json :

"frameworkAssemblies": {
  "System.Runtime": ""
}

最终,我不希望用户必须这样做 - 至少,不是为了协议缓冲区.我假设这是东西做我们如何构建Protocol Buffers的,但我不正确理解的原因,就很难解决.

我希望如果我能找到一种使dependencies入口工作的方法,那么我可以将该依赖项添加到Protocol Buffers本身,这很好 - 但是在project.lock文件中依赖于System.Runtime v4.0.0似乎没有帮助,我必须遗漏一些东西:(



1> davidfowl..:

因此,如果你眯着眼睛看看project.json,它基本上是一个带有一点goop的nuspec来描述构建项目所需的编译选项和源代码.Nuspecs今天有2个部分,frameworkAssemblies用于"内置"的东西和dependencies其他nuget依赖项.它具有相同的含义.当您使用"框架"中的内容时,需要在frameworkAssembliesvs中指定为nuget包依赖项.

现在详细说明:

在.NET Framework上使用基于PCL或.NET Core的库时,引用将引用程序集(有时称为契约程序集).其中的例子是一样的东西System.Runtime,System.Threading等等.当使用基于MSBUILD项目,有运行,基本上会自动添加一个任务,所有的的System.*引用到C#编译器来避免这个烂摊子.这些程序集在.NET Framework上称为外观.不幸的是,即使不使用它们,它也会添加所有这些.依赖性System.Runtime是此行为的触发器(在基于.NET Framework的csproj文件上运行时).

添加对同一个包的引用的原因不起作用是因为这些契约程序集(如System.Runtime)的.NET Framework文件夹(net4*)中没有任何dll.如果查看这些文件夹,您将看到一个空_._文件.这样做的原因是因为当你声明一个带有frameworkAssembly引用的nuget包时System.Runtime,msbuild项目系统无法安装它(非常复杂的bug和设计问题).

这可能会让事情更加模糊......



2> Jon Skeet..:

我已经接受大卫·福勒的回答为理由,为什么这一切发生.现在就我应该做些什么而言,看起来我只需要frameworkAssemblies在nuspec文件中添加一个元素Google.Protobuf:


  
    ...
    
      
    
  
  ...

frameworkAssembly然后,该引用最终出现在project.lock.json客户端项目中,一切都很顺利.

然而,根据大卫的其他评论判断("我们将考虑解决这个问题")无论如何我可能不需要做任何事情......



3> Oleg..:

在我看来,您的问题只是因为您选择了控制台应用程序而不是"ASP.NET Web应用程序"/"ASP.NET 5模板"/"空".我做了简单的测试用法空模板,"Google.Protobuf": "3.0.0-alpha4"从NuGet 添加,最后只是修改,Startup.cs以便它使用Google.Protobuf.WellKnownTypes:

添加 using Google.Protobuf.WellKnownTypes;

var duration = new Duration { Seconds = 100, Nanos = 5555 };里面加了Configure

修改await context.Response.WriteAsync("Hallo World!");await context.Response.WriteAsync(duration.ToString());

最终代码Startup.cs:

using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Http;
using Microsoft.Extensions.DependencyInjection;
using Google.Protobuf.WellKnownTypes;

namespace ProtobufTest
{
    public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app)
        {
            app.UseIISPlatformHandler();

            var duration = new Duration { Seconds = 100, Nanos = 5555 };

            app.Run(async context =>
            {
                await context.Response.WriteAsync(duration.ToString());
            });
        }

        // Entry point for the application.
        public static void Main(string[] args) => WebApplication.Run(args);
    }
}

生成的ASP.NET 5应用程序100.5555s在Web浏览器中成功显示.

您可以从这里下载演示项目.

更新:我分析了纯控制台DNX应用程序,它使用的代码,并可能发现的原因的问题中存在的问题duration.ToString()的方法,这在ASP.NET环境下工作,但不能在纯控制台应用程序.问题的原因很有趣,我正在尝试调查,但我想与其他人分享我目前的结果

我可以使用以下代码:

using Google.Protobuf.WellKnownTypes;
using System;

namespace ConsoleApp3
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var duration = new Duration { Seconds = 100, Nanos = 5555 };
            Console.WriteLine("{0}.{1:D4}s", duration.Seconds, duration.Nanos);
        }
    }
}

可以从这里下载工作项目.

我另外评论了这条线

//[assembly: Guid("b31eb124-49f7-40bd-b39f-38db8f45def3")]

in AssemblyInfo.cs没有不需要的引用"Microsoft.CSharp",其中有很多其他引用.该project.json示范项目包括:

{
  ...

  "dependencies": {
    "Google.Protobuf": "3.0.0-alpha4"
  },

  "frameworks": {
    "dnx451": { },
    "dnxcore50": {
      "dependencies": {
        "System.Console": "4.0.0-beta-23516"
      }
    }
  }
}

顺便说一下"System.Console": "4.0.0-beta-23516",因为名称空间(for )存在于其中所以需要包含"dnxcore50"部分内容.如果有人试图添加公共依赖项的级别,则会在文本的开头处获得错误"frameworks"ConsoleConsole.WriteLinemscorlibDNX 4.5.1"System.Console": "4.0.0-beta-23516"

错误CS0433类型'控制台'同时存在于'System.Console,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a'和'mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089'ConsoleApp3.DNX 4.5.1

更新2:可以替换线路

Console.WriteLine("{0}.{1:D4}s", duration.Seconds, duration.Nanos);

Console.WriteLine((object)duration);

使它工作.只是使用Console.WriteLine(duration);var str = duration.ToString();产生您描述的错误.

更新1:我验证代码duration.ToString()调用的线条,其使用的线路进行格式化.看来这个代码duration.ToString()确实真的一样((object)duration).ToString()WellKnownTypes类型(如Duration).

我发现最新的评论很重要.所描述的问题仅存在于dnx451(或dnx452或dnx46).如果有人会删除这些行

"dnx451": { },

"frameworks"部分project.json程序开始,程序将仅为DNX Core 5.0编译("dnxcore50").人们可以轻松验证一个人不会有任何问题.

更新4:最后我找到了解决问题的非常简单的方法:只需要"Microsoft.AspNet.Hosting": "1.0.0-rc1-final"为项目添加依赖项:

{
  "dependencies": {
    "Google.Protobuf": "3.0.0-alpha4",
    "Microsoft.AspNet.Hosting": "1.0.0-rc1-final"
  }
}

接下来加载许多不需要的dll,但现在依赖关系将被正确解析.

对于dnx451和dnxcore50,可以编译最终项目而不会出现任何问题.我将结果解释如下:"Google.Protobuf"同时适用于dnx451和dnxcore50,但是RC1的自动依赖性解析仍然存在问题,并且它无法正确解析"Google.Protobuf"的某些必需依赖项.

因为直接添加不需要的"Microsoft.AspNet.Hosting": "1.0.0-rc1-final"引用可以被视为仅一种解决方法.我认为ASP.NET 5和DNX中使用的依赖项解析仍然存在问题.我在问题发布之前发布了一段时间,但仍未解决.该问题提供了一个示例,当解析直接包含的依赖关系可以提供另一个结果作为依赖关系解析dnu restore.这就是为什么我开始比较工作代码的依赖性的原因,我最初将这些代码与非工作项目的依赖关系进行了比较.经过一些测试后,我找到了解决方法并将其减少为唯一的依赖:"Microsoft.AspNet.Hosting": "1.0.0-rc1-final".

推荐阅读
小妖694_807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有