在.NET Core应用程序1.0.0项目中引用Framework 4.6库

7
我一直在调查如何在新的.NET Core App项目中引用现有的.NET Framework 4.6库的选项。
为了证明概念,我构建了一个非常简单的.NET Framework 4.6库,将其发布为NuGet包,并将其包含在一个简单的.NET Core Web应用程序中。
目前,我似乎只能通过从project.json依赖项块中删除Microsoft.NETCore.App引用,并将frameworks属性中的netcoreapp1.0部分替换为net461块来使项目构建和运行。
完整的project.json如下:
{
  "dependencies": {
    /*"Microsoft.NETCore.App": {
      "version": "1.0.0",
      "type": "platform"
    },*/
    "Microsoft.AspNetCore.Diagnostics": "1.0.0",
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.0",
    "Microsoft.Extensions.Logging.Console": "1.0.0",
    "FileIOLibrary_1_0_0_0": "1.0.0"
  },

  "tools": {
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
  },

  /*"frameworks": {
    "netcoreapp1.0": {
      "imports": [
        "dotnet5.6",
        "portable-net45+win8",
        "net461"
      ]
    }
  },*/

  "frameworks": {
    "net461": {
      "imports": [
        "dotnet5.6",
        "portable-net45+win8"
      ]
    }
  },

  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true
  },

  "runtimeOptions": {
    "configProperties": {
      "System.GC.Server": true
    }
  },

  "publishOptions": {
    "include": [
      "wwwroot",
      "web.config"
    ]
  },

  "scripts": {
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  }
}

这基本上意味着所有的引用都是.NET Framework 4.6库。

无论如何,我有几个关于其他可用选项的问题:

  1. 是否可以指定只有我的导入库应针对.NET 4.6 Framework,而所有其他引用都应使用.NET Core?如果是这样,这意味着我可以将Microsoft.NETCore.App引用添加回项目中。
  2. 如果上述不可行,我能否将我的库重新构建为兼容的.NET标准库(我相信1.6版本在Framework 4.6和Core 1.0.0之间是兼容的)?我无法在Visual Studio中看到允许我构建针对.NET Standard的库的选项,因此如果它是一个选项,我会很感激一些指示。

一个NuGet包可以针对多个框架,但是您必须为每个框架 (.NET 462和.NET Core) 构建一个解决方案,然后将它们打包在一起。我在这里执行打包操作 (我正在使用NET452,但是问题是相同的): https://github.com/brainwipe/NJsonApiCore/blob/master/Package.nuspec这能帮助您吗? - Dr Rob Lang
如果我理解正确,我可以将这写成一个答案。但是我并不完全确定你想要达到什么目标! - Dr Rob Lang
你好,Rob。实际需求是要看看我们是否可以构建引用一些旧的.NET Framework程序集的.NET Core应用程序,最好不必重新编译我们的库(就像我上面的示例),但仍然保留尽可能多的核心功能(尽管我很清楚引用任何.NET Framework库将意味着无法使用.NET Core的优势)。如果失败,首选是重新编译库以确保它们与.NET Standard 1.6兼容,尽管我不确定您如何实际管理此操作。 - kh25
好的,我明白了,我会写出我的答案。(在此期间,答案是否定的,你不能这样做。) - Dr Rob Lang
1个回答

7

很抱歉,您不能将.NET 4.6.2 DLL加载到.NET Core应用程序中。

替代方案

在某些情况下,您可以编写一次代码,然后分别为.NET 4.6.2和.NET Core创建一个项目。两个项目指向相同的代码文件,但每个项目具有不同的框架目标。完成后,您可以构建一个NuGet包,其中包含.NET 4.6.2 DLL和.NET Core DLL,这将使部署和构建更加简单。

如何使每个框架都能够构建相同的代码文件

假设在文件夹./NET462/MyProject/中有一个MyProject.csproj和一个解决方案MySolution.sln

  1. 首先创建一个空的.NET Core库。我们将称其为MyProject.Core,并将其放在./Core/MyProject.Core/中。我们还将有一个解决方案,称之为./Core/MySolution.Core.sln
  2. 现在将原始./NET462/MyProject/中的所有文件复制到./Core/MyProject中,包括.csproj。同时也要复制解决方案,它们将共存。
  3. 如果现在加载原始解决方案,Visual Studio将抛出错误,因为project.json(由Core项目使用)和.csproj(由.NET 4.6.2项目使用)之间会发生冲突。
  4. 为了停止这种情况,创建一个名为MyProject.project.json的新文件。当加载.NET 462项目时,它是project.json的伴侣。将以下内容放入其中:

MyProject.project.json

{
    "version": "1.0.0-*",
    "description": "My Class Library",
    "authors": [
      "Your Name"
    ],
    "tags": [
      ""
    ],
    "projectUrl": "",
    "licenseUrl": "",
    "runtimes": {
      "win": {}
    },
    "frameworks": {
      "net452": {} // You might want net462
    },
    "dependencies": { 
      "Newtonsoft.Json": "9.0.1" /// Just an example of a nuget package
    }
  }
  1. 您的.NET 4.6.2项目现在应该像以前一样构建。
  2. 现在打开Core解决方案(同时打开两个Visual Studios也可以),您将看到所有文件都已添加到其中。在.NET Core / xproj下,默认情况下包含Project.json文件。您需要忽略特定于.NET 462的文件,这些是.csprojMyProject.project.json
  3. 在添加nuget软件包之前,它可能无法构建。

如何将.NET Core和.NET添加到同一个Nuget中

  1. Once each solution is built in Release mode, you will have two outputs, a DLL for each of the frameworks. You can change the name of the DLLs in the project files (.csproj and project.json respectively) but nuget doesn't care.
  2. Create a package.nuspec file and put the following in it:

    <!-- language: lang-xml -->
    <?xml version="1.0"?>
    <package>
      <metadata>
        <id>MyProject</id>
        <version>1.0.0</version>
        <authors>Me</authors>
        <owners>Me</owners>
        <projectUrl></projectUrl>
        <iconUrl>FILL ME IN</iconUrl>
        <description>FILL ME IN</description>
        <copyright>FILL ME IN</copyright>
        <releaseNotes>First attempt</releaseNotes>
        <tags>FILL ME IN</tags>
        <dependencies>
          <group targetFramework="dotnet">
            <dependency id="Newtonsoft.Json" version="9.0.1" />
          </group>
          <group targetFramework="net452">
            <dependency id="Newtonsoft.Json" version="9.0.1" />
          </group>
        </dependencies>
        <frameworkAssemblies>
          <frameworkAssembly assemblyName="System.Core" targetFramework="net452"/>
          <frameworkAssembly assemblyName="System.Core" targetFramework="dotnet" />
        </frameworkAssemblies>
      </metadata>
      <files>
        <file src="Core\MyProject\bin\release\MyProject.dll" target="lib/net452" />
        <file src="Core\MyProject\bin\release\MyProject.Core.dll" target="lib/dotnet" />
      </files>
    </package>
    
  3. Use this to build your nuget package and when including in your main system, nuget will serve the correct package.

更大的例子

我的JsonApi库能够做到这一点,此外它还有两个Web项目,一个是.NET 4.6.2的,一个是.NET Core的,因为它们使用不同的基类。主要共享库被两个项目都使用。

重要提示

您的.NET 4.6.2依赖的某些库将无法在您的Core应用程序中使用。我做过两次,都因为System.Web导致了问题。.NET 4.6.2中的System.Web实际上是IIS的一个包装器。找出最好的方法是尝试合并上述项目,并将nuget包添加到project.json中,直到您遇到在Core中不存在的内容为止。

事情正在改变

.NET团队在2016年5月表示,他们将在2016年底停止使用project.json。到那时,我想这些问题可能会消失,因为Visual Studio应该能够处理两种共存的.csproj。根据您的商业情况,我建议等待这个改变!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接