Automatically enable RazorGenerator for new views

Sep 6, 2013 at 2:58 AM
When adding a new razor view to a project is it possible to automatically enable RazorGenerator on this view?

Cheers,
Is.
Coordinator
Sep 6, 2013 at 5:04 AM
Note sure this is possible, unless there was an item template that explicitly did this.
Sep 6, 2013 at 5:44 AM
David,

Is it possible to automate Enable-RazorGenerator or Redo-RazorGenerator as a pre-build event?

I would very much like to use RazorGenerator in our web app, however it is not a nice experience to have to "remember" to run the nuget console command every single time one of my team adds a new view to the project.
Coordinator
Sep 6, 2013 at 5:49 AM
RazorGenerator.msbuild might do what you want. See the doc.
Sep 10, 2013 at 5:43 AM
David,

The msbuild task does not suit our requirement, it attempts to compile all views on the filesystem, however we have views (and associated models) on the filesystem which are not included in the solution. As such the views that are excluded from the solution fail the msbuild task.

Any other ideas?

Cheers.
Coordinator
Sep 10, 2013 at 5:38 PM
@israeld, you should be able to specify the files you want to precompile by specifying an ItemGroup in your project:
<ItemGroup>
    <RazorSrcFiles Include="Views\Admin\**\*.cshtml" />
    <RazorSrcFiles Include="Views\Contacts\**\*.cshtml" />
</ItemGroup>
More details on MsBuild ItemGroups here - http://msdn.microsoft.com/en-us/library/vstudio/646dk05y.aspx
Sep 11, 2013 at 5:24 AM
Yes this would work, however again there's a manual step required to edit the csproj file when a new subfolder is added under Views. I would really like to avoid manual steps because there's always the chance that someone will miss a manual step.

I have quickly written my own Visual Studio add-in which intercepts when a new file is added to a project. If the file has the "cshtml" extension and the containing project contains a reference to RazorGenerator.Mvc then it automatically sets the custom tool value.

I wrote this code very quickly so it may not be "production ready" but I've included it if you are at all interested.
private ProjectItemsEvents ProjectItemsEvents;
private SolutionEvents SolutionEvents;
private Dictionary<string, bool> EnabledByProjectName;

public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
{
    _applicationObject = (DTE2)application;
    _addInInstance = (AddIn)addInInst;

    SolutionEvents = _applicationObject.Events.SolutionEvents;
    SolutionEvents.Opened += delegate()
    {
        EnabledByProjectName = new Dictionary<string, bool>();
    };

    ProjectItemsEvents = ((EnvDTE80.Events2)_applicationObject.Events).ProjectItemsEvents;
    ProjectItemsEvents.ItemAdded += delegate(ProjectItem ProjectItem)
    {
        if (ProjectItem.Name.ToLower().EndsWith(".cshtml"))
        {
            var project = ProjectItem.ContainingProject;

            if (project != null)
            {
                if (!EnabledByProjectName.ContainsKey(project.Name))
                {
                    var vsProj = project.Object as VSLangProj.VSProject;

                    if (vsProj != null)
                    {
                        var enabled = false;

                        foreach (VSLangProj.Reference reference in vsProj.References)
                        {
                            if (reference.Name == "RazorGenerator.Mvc")
                            {
                                enabled = true;
                                break;
                            }
                        }

                        EnabledByProjectName.Add(project.Name, enabled);
                    }
                }

                if (EnabledByProjectName[project.Name])
                {
                    ProjectItem.Properties.Item("CustomTool").Value = "RazorGenerator";
                }
            }
        }
    };
}