IntelliSense support for foreign assemblies

Aug 9, 2011 at 10:54 PM

RazorGenerator is making my life a whole lot easier for the most part, which I'm really grateful for, but I have a niggle that is slowly getting on my nerves.

I have implemented various MVC 'areas' in separate assemblies, and each of these assemblies references a core assembly for HtmlHelper extension methods etc.  However, despite IntelliSense working fine for normal things when editing the razor views, anything to do with the separate assembly is highlighted as an error and there is no code completion support for it.  It still compiles and works fine, so I can live with it, it's just really annoying.  Like when I'm trying to type lambda functions it's not expecting it so when I hit 'x[space]' (as part of 'x => x.ID', say) I get 'XhtmlMobileDocType '.  I also don't like staring at red underlines all the time.

This includes everything to do with the separate assembly: the namespace isn't recognised in the @using directive, the @Html extension methods are not found, and while I have code completion support for the Model type, inherited members of the Model type defined in a base class which resides in the foreign assembly are not listed.

Any suggestions?

Thanks!

Coordinator
Aug 10, 2011 at 1:14 AM

Seems there is indeed an issue in this scenario, but I don't yet fully understand what's going on. Note that Razor intellisense comes from VS, and VS really has no idea that we're using the generator. So we get whatever intellisense VS would provide if you were not using the generator. In most cases, it's the same thing, but sometimes it may not be.

Here, we need to understand exactly how the VS Razor intellisense figures out the list of available assemblies. I have emailed a couple people who should know something about this, and hopefully there is a good solution!

Aug 10, 2011 at 3:45 AM

David,

In the file \mvc3-rtm-sources\webpages\src\System.Web.WebPages.Razor\Configuration\RazorPagesSection.cs, the web.config file in the Views folder is parsed, and the namespaces within the pages pageBaseType element are parsed into a NamespacesCollection element, which is then consumed in the file \mvc3-rtm-sources\webpages\src\System.Web.WebPages.Razor\WebRazorHostFactory.cs.

The upshot appears to be in the method used to create the WebPageRazorHost.  If the CreateHostFromConfig() method is invoked, then all namespaces explicitly added in the web.config file should be available (and should have IntelliSense support).

counsellorben

Coordinator
Aug 10, 2011 at 4:40 AM

What you describe is the runtime behavior, and at runtime everything is working fine. What's at stake here is what happens at design time when it comes to giving Razor intellisense, and I suspect that the logic is different.

Also, note that the issue is not about namespaces, but about assembly references. If the design time logic doesn't know about the correct list of referenced assemblies, then it can't make sense of the namespaces in those assemblies.

Aug 10, 2011 at 2:02 PM
Edited Aug 10, 2011 at 2:30 PM

David,

I understand, and after developing a workaround which gets Razor IntelliSense working for other namespaces, I humbly retract my earlier email.

In order to get IntelliSense working, I had to do the following. 

1.  I created a new ASP.NET MVC 3 Web Application project (Project 2), and added the NuGet packages for the PreCompiledViewEngine and MvcMiniProfiler.

2.  I ran the new website.  This apparently triggers Razor IntelliSense to accept other namespaces, such as MvcMiniProfiler (though there is a whole discussion about why this must be in itself).

3.  I removed the Contents, Controllers, Models and Scripts folders from Project 2, so it is essentially a precompiled view library.

4.  I added Project 2 to my solution containing an MVC 3 Web Application (Project 1), and added a reference in Project 1 to Project 2, so that Project 1 will use the precompiled views built in Project 2.

This gave me a project with full Razor IntelliSense, which I now can use as a precompiled view library.

counsellorben

P.S.  To add any HtmlHelpers to Razor IntelliSense, you must add the namespace for your helpers to the namespaces collection in the web.config file in the Views folder (and in any Areas), then you must unload and reload your precompiled view library project.

Coordinator
Aug 10, 2011 at 5:14 PM

I see. So basically the trick is to use an MVC project instead of a library project. This sort of makes sense since the VS Razor support was designed for MVC apps, and library projects normally don't have Razor files.

Maybe that's just the way to go...

Aug 11, 2011 at 12:29 PM


Thanks very much for the replies.

That could be a fair enough workaround until there is some sort of native VS support for "area assemblies" ( hopefully, sometime ;) ).

Cheers,

Stewart.

Aug 11, 2011 at 3:02 PM

I can confirm that the code completion all works as expected if you start off with a web project as suggested.  My thanks to counsellorben.

To be honest it makes a lot of sense to do it this way actually, as it gives you nice things such as "Add > Area" and "Go To View" menu items.  I hadn't thought of doing it this way before because I wasn't really thinking of a web project as basically just a class library.

Coordinator
Aug 11, 2011 at 9:56 PM

Indeed, the fact that it being an MVC project gives you access to those extra menu items makes it a generally better choice that a plain Library.

Oct 13, 2011 at 10:14 PM

I found the answer to this via this blog post:

http://blogs.msdn.com/b/webdevtools/archive/2011/01/20/how-to-get-razor-intellisense-for-model-in-a-class-library-project.aspx

Basically, you just need a class library to have a web.config with the proper namespaces and assemblies defined and it all works again!  Just what I was looking for...