2

I have an open source class library that targets MVC 2, 3, 4, and 5. I use the same project file for every version and use a compilation constant to switch between project references, as follows.

<ItemGroup Condition=" $(DefineConstants.Contains('MVC3')) ">
    <!--<Reference Include="System.Web.Mvc, Version=3.0.0.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />-->
    <Reference 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>

The MVC 4 references are working fine, but I am unable to find a MVC 3 configuration that will build on machines without the Windows Update that will also build on machines with the Windows Update. Since this is an open source project that has dozens of developers building it, I need to provide a solution that will work whether or not the update is installed.

I have already gone through all of the information on the following posts:

As per the configuration above, I have already tried changing from the GAC reference to using the NuGet package. However, that doesn't work if I try to build on a machine that doesn't have this update installed (including the build server, which isn't under my direct control). Using the original configuration no longer builds on a machine with the Windows Update installed. Using the new GAC reference works on a machine with the update installed, but not on one that doesn't have it installed.

I tried setting the copy local property, but it doesn't work right since I am referencing 4 different versions of MVC - setting it to true on one reference toggles the other references back off again.

Also, the general consensus is that you can fix this issue using assembly binding redirects. But since my project is a class library with no configuration file of its own, how would you accomplish that? I searched to see if there is a way to redirect bindings via .NET attributes, but I can't seem to find anything useful. My DLL won't build, and fails with similar errors as the other issues I linked to above, so it does no good to put binding redirects into a web.config file that will be physically located in another project. I tried adding an app.config file to my project with the binding redirects for MVC 3, but it didn't work.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
                <bindingRedirect oldVersion="3.0.0.0-3.0.0.1" newVersion="3.0.0.1"/>
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
</configuration>

Are there any other options that are not in any of the above referenced documents that can be used to make a class library that references MVC 3 compile on machines that have the Windows Update MS14059 installed as well as machines that don't have it installed?

Community
  • 1
  • 1
NightOwl888
  • 55,572
  • 24
  • 139
  • 212

1 Answers1

2

So far, what I have come up with for a solution is to conditionally include the correct MVC assembly depending on whether the MVC 3.0.0.0 assembly exists in the GAC.

<!-- 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>
NightOwl888
  • 55,572
  • 24
  • 139
  • 212