In our project we're using the razorgenerator of David Ebbo. This allowed us to move some of our cshtml files to a class library.
What we would like to achieve now is the following:
- MyCommonViews has a "MyView.cshtml" in its Views folder.
- MyWebProject ALSO has a "MyView.cshtml" in its Views folder.
- MyOtherWebProject DOES NOT have a "MyView.cshtml" in its Views folder.
When MyOtherWebProject needs to load MyView.cshtml, it will pick the one which is in the compiled MyCommonViews project. That is what we want.
BUT when MyWebProject needs to load MyView.cshtml, we would like it to pick up the "overridden" MyView.cshtml file which is in the MyWebProject itself.
Is what we want possible and how?
Manu.
There is flag
PreemptPhysicalFiles = false
which does the magic.Full sample:
However there is maybe a small bug: http://razorgenerator.codeplex.com/workitem/100
You can also try CompositePrecompiledMvcEngine from RazorGenerator.Mvc 2.1.0. It was designed for correct support of view overriding within multiple assemblies. Piece of code:
The first line will register all views from the MyCommonViews assembly (~/Views/MyView.cshtml), the second line will register all views from the MyWebProject or MyOtherWebProject assembly.
When it encounters the virtual path, that already has been registered (~/Views/MyView.cshtml from the MyWebProject assembly), it overrides an old mapping with a new view type mapping.
If another project doesn't has view with the same virtual path (MyOtherWebProject) it leaves source mapping unchanged.
I wrote up a hacky solution for our problem. It hacks into the razorgenerators viewengine and removes all appropriate entries from the (private readonly) Dictionary it has.
The code is ran on application start.
Talk is cheap, show me the code:
WebConfigSettings.RootPath contains the path on HD to the root of our web application.
This is a part of our static ReflectionUtils class:
This did the trick. We basically force the PrecompiledMvcEngine to "forget" any view which we have in our concrete project.