RazorGenerator inside a NuGet package

May 13, 2013 at 3:55 PM
We have a heavily automated build system and a number of widely-used internal libraries. We use NuGet (and our own NuGet server) to pack up the libraries and make dependency tracking easy. Recently we started switching our MVC libraries to use RazorGenerator and WebActivator to make project creation and management easy.

Here's our use case and our problem:

We have a package (MyPackage.MyArea) that has an MVC area in the root (Views/Home, Views/Other, etc). We install RazorGenerator.Mvc and RazorGenerator.Msbuild into the project. In the App_Start/RazorGeneratorMvcStart.cs the PrecompiledMvcEngine has the baseVirtualPath set (Areas/MyArea). Then this project is packed up into a NuGet package.

And installed in MyFinalProject.

Because of NuGet package dependency, both RazorGenerator.Mvc and RazorGenerator.Msbuild are installed on MyFinalProject, which generates a new App_Start/RazorGeneratorMvcStart.cs file.

All seems well until I want to go to http://localhost/MyArea/Home/Index I get served the final project ~/Views/Home/Index.cshtml instead of the pre-compiled ~/Areas/MyArea/Home/Index.cshtml
This seems to be because the PrecompiledMvcEngine for MyFinalProject is added later than, and in front of, the engine from MyPackage.MyArea so when the MyArea HomeController Index action returns View(), the view engines list starts looking first through MyFinalProject, finds a matching view in ~/Views/Home/Index.cshtml and quits looking, even though a more specific view is available in the next engine in the list.

There are (from what I can tell) 3 ways to work around this, each with issues:
1) Remove App_Start/RazorGeneratorMvcStart.cs from MyFinalProject, which is fine until the next time I update RazorGenerator.Mvc, at which point it gets re-added....
2) Alter the ViewEngines.Engines.Insert statement in MyFinalProject to insert AFTER the engine from MyPackage.MyArea, which is fine unitl I start dealing with multiple MVC view packages, which might each have this issue with each other...
3) Disable RazorGeneratorMvcStart from running in MyFinalProject by disabling the WebActivator line at the top of the file.

The problem is we don't want to do any of these, as they are all manual work-arounds and fixes. There are many developers working on many projects and we want to minimize the chance of encountering upkeep project creation issues by automating this as much as possible, which is why we want to use pre-built and compiled areas and views for our common code, so we can centralize the look and feel of our code.

Does anyone have suggestions on how I can remove this conflict of areas, or perhaps remove RazorGenerator from MyFinalProject entirely?
May 19, 2013 at 12:39 AM
Edited May 28, 2013 at 5:21 PM
The App_Start code that comes with the NuGet package is really just a convenient way to register things, but it is very much meant to be modified. That's why it is brought in as source code rather than as part of an assembly. The same is generally true of all NuGet packages that bring in source code.

As such, it doesn't seem like a big deal to me to have to make some slight modifications. If you really don't want that, I suppose you could write a simple NuGet package that warps that RG.Mvc package, and then modifies it as you need.
May 28, 2013 at 9:40 AM
Hi! I'm having the exact same problem. I am the lead developer for Piranha CMS (piranhacms.org) which is an open source cms framework for .NET. In our upcoming release we have moved to MVC4 and decided to use RazorGenerator instead of VirtualPathProviders for the resolving the views of the manager interface which is compiled into the core-dll of the package.

The problem now is that when we're packing the NuGet-package for the release, RazorGenerator.Mvc is needed for the application to run (since the embedded manager interface is dependent on it), but adding it as a package-reference installs the App_Start code-files which is not desired in the application solution, the view engines are registered on startup by the core library.

Without a NuGet-package just including the dll-files my only solution is to include the dll in the our NuGet-package instead , which I don't know if I can do since your package is licensed with MS-PL and Piranha CMS is licensed with LGPL which is not 100% compatible. Do you have any suggestion on this?
May 28, 2013 at 2:52 PM
If licensing is the only reason you aren't able to include the binaries with your solution, we could explore releasing a version under Apache. According to this Stackoverflow article - http://stackoverflow.com/questions/1174240/apache-and-lgpl-license-compatibility - this should be fully compatible with LGPL.
May 28, 2013 at 10:31 PM
Hi again, that looks like a good option. How would we go about this? Make sure to bundle up all licenses and other notifications that you want to be included in the package, and thanks for a solid package, it really does the job and improves performace as well!

May 28, 2013 at 10:54 PM
Actually, we're already using Apache in some of our other projects, so I simply switched RazorGenerator to use it. So you should be all set!