2015-08-23 7 views
14

Contribuisco a una libreria open source che attualmente supporta MVC 2 - MVC 5 e desidero supportare anche MVC 6 (e oltre). Per supportare ciascuna versione di MVC, sfruttiamo la funzionalità Condition di MSBuild per includere la versione corretta di MVC e le sue dipendenze durante la creazione di una build (in base al valore di DefineConstants). Ciò rende possibile l'utilizzo di un singolo file di progetto per tutte le versioni supportate di MVC, creando una singola DLL per ciascuna versione MVC utilizzando lo stesso file di progetto e il codice sorgente.Supporto di più versioni di una dipendenza di compilazione (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> 

ho guardato la struttura del progetto di ASP.NET 5/6 MVC e hanno già rassegnato a utilizzare un file project.json anziché un file .csproj per MVC 6. Tuttavia, ho letto il project.json documentation e ci doesn' t sembra essere un modo per supportare più versioni di MVC con un singolo file project.json.

Idealmente, mi piacerebbe abbandonare MSBuild e utilizzare Roslyn per ogni versione MVC (incluso MVC 2 - MVC 5) andando avanti. Ma esiste un modo per supportare più versioni MVC senza dover creare un file di progetto (e la directory del progetto poiché tutti dovrebbero essere denominati project.json) per ogni versione MVC? In caso contrario, esiste un altro modo per non dover duplicare tutta la configurazione project.json per 5 volte?

risposta

1

Ho trovato una (non così buona) soluzione alternativa al problema. Mi piacerebbe ancora sapere se c'è un modo migliore.

La soluzione che ho trovato è quella di utilizzare il globbing per includere i file da compilare al di fuori della directory del progetto. Ad esempio, la mia struttura del progetto è simile al seguente:

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 

Tutti i file sono inclusi nel .csMyProject. E poi il mio file project.json assomiglia a questo:

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

Tuttavia, c'è un altro problema con questa soluzione - Visual Studio 2015 non mostra nessuno dei file in MyProject.MVC6 perché sono inclusi solo per la compilazione. Inoltre, non è possibile includere il file .csproj poiché ciò non comporterà la compilazione dell'intero progetto.

Quindi, mi si avvicinò con un'altra soluzione - per includere un file project.json e MyProject.DNX.Debug.xproj di file all'interno del progetto reale e includo questo nella soluzione MVC6 invece del file .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 

Questi file servono solo per fornire un modo per eseguire il debug di loro in MVC6, l'idea è che quando MVC7 esce sarò in grado di creare un'altra cartella del progetto e poi scambiare questa configurazione in base alle esigenze per le quali la versione per eseguire il debug .

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 

Questo è ancora molto lontano dall'ideale. Si prega di fornire una risposta migliore se ce n'è uno.

0

è possibile creare un unico progetto che compila a più runtime .NET cioè Core NET 4.5.1 ecc

  1. File -> Nuovo progetto.
  2. Web -> Libreria di classi (pacchetto)
  3. Modificare il file project.json.
  4. Sotto l'elemento frameworks, è possibile immettere più framework. Qui sto il targeting .NET Core e .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. Poi nel codice è possibile utilizzare le direttive di pre-processore di scrivere codice specifico per un particolare quadro o runtime.

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

Questo non funziona (almeno non come lo avete). Stiamo compilando una DLL separata per .NET 3.5, .NET 4.0 e .NET 4.5 solo per MVC2. MVC3 e MVC4 sono compilati in .NET 4.0 e .NET 4.5 e MVC5 solo in .NET 4.5. Abbiamo simboli di compilazione per sfruttare progressivamente le nuove funzionalità. Ad esempio, ce n'è uno attorno all'attributo 'AllowAnonymous' perché non era supportato in MVC2 o MVC3 ma è richiesto per MVC4 e MVC5 per garantire che le persone con AuthorizeAttribute registrate globalmente possano sempre accedere al controller. Stai dicendo che dovrei mappare una versione di MVC su un singolo framework? – NightOwl888

+0

Ah, capisco. In tal caso, sì, stai facendo la cosa giusta e la tua risposta è corretta. –