2015-08-23 18 views
14

Ich spreche zu einer Open Source-Bibliothek, die derzeit MVC 2 - MVC 5 unterstützt, und ich möchte auch MVC 6 (und darüber hinaus) unterstützen. Um die einzelnen Versionen von MVC zu unterstützen, nutzen wir die Funktion Condition von MSBuild, um die korrekte Version von MVC und seine Abhängigkeiten beim Erstellen eines Builds einzubeziehen (abhängig vom Wert DefineConstants). Dies ermöglicht die Verwendung einer einzelnen Projektdatei für alle unterstützten MVC-Versionen, indem für jede MVC-Version mit derselben Projektdatei und demselben Quellcode eine individuelle DLL erstellt wird.Unterstützung mehrerer Versionen einer Kompilierungsabhängigkeit (vNext)

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

ich an der Projektstruktur von ASP.NET 5/MVC 6 und haben ihren Rücktritt erklärt schon eher eine project.json Datei zu verwenden, ausgesehen haben als eine .csproj Datei für MVC 6. Allerdings las ich die project.json documentation und es doesn‘ t scheint eine Möglichkeit zu sein, mehrere Versionen von MVC mit einer einzigen project.json Datei zu unterstützen.

Idealerweise würde ich gerne MSBuild abwerfen und Roslyn für jede MVC-Version (einschließlich MVC 2 - MVC 5) verwenden. Aber gibt es eine Möglichkeit, mehrere MVC-Versionen zu unterstützen, ohne eine Projektdatei (und ein Projektverzeichnis, da sie alle project.json heißen müssten) für jede MVC-Version zu erstellen? Wenn nicht, gibt es einen anderen Weg, um nicht alle project.json Konfiguration 5 Mal zu duplizieren?

Antwort

1

Ich fand eine (nicht so gute) Abhilfe für das Problem. Ich würde immer noch gerne wissen, ob es einen besseren Weg gibt.

Die Lösung, die ich gefunden habe, ist die Verwendung von Globbing, um Dateien außerhalb des Projektverzeichnisses zu kompilieren. Zum Beispiel sieht meine Projektstruktur wie folgt aus:

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 

Alle der .cs Dateien werden in MyProject enthalten. Und dann sieht meine project.json-Datei wie folgt:

{ 
    "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" 
     } 
    } 
    } 
} 

Allerdings gibt es ein weiteres Problem mit dieser Lösung - Visual Studio 2015 zeigt nicht alle Dateien in MyProject.MVC6, weil sie nur für die Kompilierung enthalten sind. Außerdem ist es nicht möglich, die Datei .csproj einzuschließen, da dies dazu führt, dass das gesamte Projekt nicht kompiliert wird.

So kam ich mit einem anderen Problem zu umgehen up - enthalten eine project.json Datei und MyProject.DNX.Debug.xproj Datei innerhalb des aktuellen Projektes und ich um diesen einen in die MVC6 Lösung anstelle der .csproj Datei.

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 

Diese Dateien dienen nur einen Weg, um sie in MVC6 zu debuggen, ist die Idee, dass, wenn MVC7 kommt aus ich in der Lage sein wird, ein anderes Projekt-Ordner zu erstellen und dann diese Konfiguration tauschen wie für welche Version zu debuggen benötigt .

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 

Dies ist immer noch sehr weit vom Ideal entfernt. Bitte geben Sie eine bessere Antwort, wenn es eine gibt.

0

Sie können ein einzelnes Projekt erstellen, die mehrere Runtimes heißt .NET Kern kompiliert, .NET 4.5.1 usw.

  1. Datei -> Neues Projekt.
  2. Web -> Klassenbibliothek (Paket)
  3. Bearbeiten Sie die Datei project.json.
  4. Unter dem Element frameworks können Sie mehrere Frameworks eingeben. Hier bin ich Targeting .NET-Core und .NET 4.5.1:

    "frameworks": { 
        "dnx451": { 
         "frameworkAssemblies": { 
          "System.Net.Http": "4.0.0.0",   // Example reference 
         } 
        }, 
        "dnxcore50": { 
         "dependencies": { 
          "System.Net.Http": "4.0.1-beta-23225" // Example reference 
         } 
        } 
    } 
    
  5. Dann in Ihrem Code können Sie Pre-Prozessor-Richtlinien verwenden, um Code spezifisch für einen bestimmten Rahmen oder Laufzeit zu schreiben.

    public void Foo() 
    { 
        #if DNX451 
        // Code specific to .NET 4.5.1 
        #endif 
    } 
    
+0

Das wird nicht funktionieren (zumindest wie Sie es nicht haben). Wir kompilieren eine separate DLL für .NET 3.5, .NET 4.0 und .NET 4.5 nur für MVC2. MVC3 und MVC4 werden unter .NET 4.0 und .NET 4.5 und MVC5 nur unter .NET 4.5 kompiliert. Wir haben Kompilierungssymbole, um progressiv neue Funktionen zu nutzen. Zum Beispiel gibt es eines um das Attribut "AllowAnonymous", weil dieses in MVC2 oder MVC3 nicht unterstützt wurde, aber für MVC4 und MVC5 erforderlich ist, um sicherzustellen, dass Personen mit global registrierten AutorizeAttribute immer auf den Controller zugreifen können. Wollen Sie sagen, ich sollte eine MVC-Version auf ein einzelnes Framework abbilden? – NightOwl888

+0

Ah, ich verstehe. In diesem Fall, ja, Sie tun das Richtige und Ihre Antwort ist richtig. –

Verwandte Themen