支持多个版本的编译依赖项(vNext)

Nig*_*888 15 c# asp.net-mvc roslyn asp.net-core-mvc asp.net-core

我参与了一个目前支持MVC 2 - MVC 5的开源库,我也想支持MVC 6(以及更高版本).为了支持每个版本的MVC,我们利用MSBuild 的Condition特性在构建时包含正确版本的MVC及其依赖项(取决于其值DefineConstants).通过使用相同的项目文件和源代码为每个MVC版本创建单独的DLL,可以为所有受支持的MVC版本使用单个项目文件.

<ItemGroup Condition=" $(DefineConstants.Contains('MVC2')) ">
    <Reference Include="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
</ItemGroup>
<ItemGroup Condition=" $(DefineConstants.Contains('MVC3')) ">
    <!-- Due to the windows update MS14-059, we need this hack to ensure we can build MVC3 both on machines that have the update and those that don't -->
    <Reference Condition=" Exists('$(windir)\Microsoft.NET\assembly\GAC_MSIL\System.Web.Mvc\v4.0_3.0.0.0__31bf3856ad364e35\System.Web.Mvc.dll') " Include="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
    <Reference Condition=" !Exists('$(windir)\Microsoft.NET\assembly\GAC_MSIL\System.Web.Mvc\v4.0_3.0.0.0__31bf3856ad364e35\System.Web.Mvc.dll') " Include="System.Web.Mvc, Version=3.0.0.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
        <Private>True</Private>
        <HintPath>..\packages\Microsoft.AspNet.Mvc.3.0.20105.1\lib\net40\System.Web.Mvc.dll</HintPath>
    </Reference>
    <Reference Include="System.Web.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
        <Private>True</Private>
        <HintPath>..\packages\Microsoft.AspNet.Razor.1.0.20105.408\lib\net40\System.Web.Razor.dll</HintPath>
    </Reference>
    <Reference Include="System.Web.WebPages.Razor, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
        <Private>True</Private>
        <HintPath>..\packages\Microsoft.AspNet.WebPages.1.0.20105.408\lib\net40\System.Web.WebPages.Razor.dll</HintPath>
    </Reference>
</ItemGroup>
<ItemGroup Condition=" $(DefineConstants.Contains('MVC4')) ">
    <Reference Include="System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
        <Private>True</Private>
        <HintPath>..\packages\Microsoft.AspNet.Mvc.4.0.20710.0\lib\net40\System.Web.Mvc.dll</HintPath>
    </Reference>
    <Reference Include="System.Web.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
        <Private>True</Private>
        <HintPath>..\packages\Microsoft.AspNet.Razor.4.0.20715.0\lib\net40\System.Web.Razor.dll</HintPath>
    </Reference>
    <Reference Include="System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
        <Private>True</Private>
        <HintPath>..\packages\Microsoft.AspNet.WebPages.4.0.20710.0\lib\net40\System.Web.WebPages.Razor.dll</HintPath>
    </Reference>
</ItemGroup>
<ItemGroup Condition=" $(DefineConstants.Contains('MVC5')) ">
    <Reference Include="System.Web.Mvc, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
        <Private>True</Private>
        <HintPath>..\packages\Microsoft.AspNet.Mvc.5.0.0\lib\net45\System.Web.Mvc.dll</HintPath>
    </Reference>
    <Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
        <Private>True</Private>
        <HintPath>..\packages\Microsoft.AspNet.Razor.3.0.0\lib\net45\System.Web.Razor.dll</HintPath>
    </Reference>
    <Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
        <Private>True</Private>
        <HintPath>..\packages\Microsoft.AspNet.WebPages.3.0.0\lib\net45\System.Web.WebPages.dll</HintPath>
    </Reference>
    <Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
        <Private>True</Private>
        <HintPath>..\packages\Microsoft.AspNet.WebPages.3.0.0\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
    </Reference>
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)

我已经看过ASP.NET 5/MVC 6的项目结构,并且已经辞职使用project.json文件而不是.csprojMVC 6 的文件.但是,我读了project.json文档并且似乎没有办法使用单个project.json文件支持多个版本的MVC .

理想情况下,我想放弃MSBuild并使用Roslyn每个MVC版本(包括MVC 2 - MVC 5).但有没有办法支持多个MVC版本,而不必project.json为每个MVC版本创建一个项目文件(和项目目录,因为所有这些文件必须被命名)?如果没有,是否有另一种方法可以不必复制所有project.json配置5次?

Nig*_*888 2

我找到了解决该问题的(不太好的)方法。我还是想知道有没有更好的办法。

我想出的解决方案是使用 globbing 来包含要在项目目录之外编译的文件。例如,我的项目结构如下所示:

MyProject.sln
// This is where the legacy MVC2-5 support goes
MyProject/
    MyProject.csproj
// This is where the MVC6 support is compiled from
MyProject.MVC6/
    MyProject.MVC6.xproj
    project.json
Run Code Online (Sandbox Code Playgroud)

所有.cs文件都包含在MyProject. 然后我的project.json文件如下所示:

{
  "version": "1.0.0-*",
  "description": "MyProject Description",

  "dependencies": {
    "Microsoft.AspNet.Mvc": "6.0.0-beta7",
    "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-beta7",
    "Microsoft.AspNet.Routing": "1.0.0-beta7"
  },

  "compile": "../MyProject/**/*.cs",

  "compilationOptions": {
    "define": ["MVC6", "NET46"]
  },

  "frameworks": {
    "dnxcore50": {
      "dependencies": {
        "Microsoft.CSharp": "4.0.1-beta-23225",
        "System.Collections": "4.0.11-beta-23225",
        "System.Linq": "4.0.1-beta-23225",
        "System.Runtime": "4.0.21-beta-23225",
        "System.Threading": "4.0.11-beta-23225"
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,此解决方案还存在另一个问题 - Visual Studio 2015 不会显示任何文件,MyProject.MVC6因为它们仅包含在编译中。此外,不可能包含该.csproj文件,因为这会导致整个项目无法编译。

因此,我想出了另一种解决方法 - 在实际项目中包含一个project.json文件和MyProject.DNX.Debug.xproj一个文件,并将这个文件而不是文件包含到 MVC6 解决方案中.csproj

MyProject.sln
// This is where the legacy MVC2-5 support goes
MyProject/
    MyProject.csproj
    MyProject.DNX.Debug.xproj
    project.json
// This is where the MVC6 support is compiled from
MyProject.MVC6/
    MyProject.MVC6.xproj
    project.json
Run Code Online (Sandbox Code Playgroud)

这些文件仅提供一种在 MVC6 中调试它们的方法,其想法是,当 MVC7 发布时,我将能够创建另一个项目文件夹,然后根据需要交换此配置以调试哪个版本。

MyProject.sln
// This is where the legacy MVC2-5 support goes
MyProject/
    MyProject.csproj
    MyProject.DNX.Debug.xproj 
    project.json // This project will be swapped between MVC6 and MVC7 based on compilationOptions
// This is where the MVC6 support is compiled from
MyProject.MVC6/
    MyProject.MVC6.xproj
    project.json
// This is where the MVC7 support is compiled from
MyProject.MVC7/
    MyProject.MVC7.xproj
    project.json
Run Code Online (Sandbox Code Playgroud)

这离理想还很远。如果有的话请提供更好的答案。