Re-using external view components in ASP.NET 5 & ASP.NET MVC 6

The other day we explored using view components in ASP.NET 5 – as a very nifty replacement for the old MVC ChildActions. View components allow you to package a piece of functionality into a reusable class, along with an accompanying view, that can be invoke from any other view on demand.

Today let’s take this a step further – and let’s see how you can configure ASP.NET MVC 6, to be able to consume view components not just from the current web project but from external sources – external assemblies too. This way you will be able to share and distribute your view components across multiple projects. This is definitely useful for anyone who has – for example – ever worked on a portal-style applications, where building reusable components is one of the most important development activities.

The requirements

While the latest version of ASP.NET 5 at the time of writing is RC1, this particular feature that I am going to be using is only available in the latest code (which is going to become RC2 in some – near? – future). For now, in order to be able to follow along, we’ll be pulling the packages from the CI feed at You can either modify your machine nuget packages sources (although that’s a bit brave), or just add a nuget.config file, pointing to the CI feed, to your solution root:

By the way, all of the source code for this article is available at Github.

Set up

In order to be able to use view components from external assemblies we will rely on a feature called file providers – represented in ASP.NET 5 by an interface IFileProvider. It allows you to instruct ASP.NET 5 from where the files (such as for example MVC views) that should be used within the application are coming from. RoslynCompilationService, when compiling your application, is going to rely on the file provider to discover files.

By default, to find Razor views, ASP.NET MVC 6 preregisters the PhysicalFileProvider, an implementation of IFileProvider that looks at all the files in the base path of your application.

In MVC 6, since RC2 RazorViewEngineOptions, which can be configured at your MVC application startup, will enable you to set multiple IFileProviders that the MVC framework is going to consult (in addition to the default PhysicalFileProvider, or even instead of it – since it can be removed too) when looking for files. At this point it should be pretty self explanatory – normally MVC 6 would only look at the current project to discover views. With the possibility to register extra providers, you can instruct the framework to additionally look at an external assembly and consider the embedded resources from there too.

What happens under the hood, is that the framework actually relies on a new implementation of IFileProvider, called CompositeFileProvider (also introduced in RC2), which is simply able to wrap multiple IFileProviders, and expose the files provided by them using a single common interface.

As mentioned, this change was only introduced recently – if you tried this against the RC1 version of the code, you’d have noticed that only a single IFileProvider was allowed for an MVC application in that version. That obviously made it impossible to efficiently share things such as view components. After all, if you chose an external file provider – pointed it to external assembly – the framework would no longer discover your “web project” views anymore as it would replace the default PhysicalFileProvider.


So let’s start by creating an empty ASP.NET 5 application. I am going to reference all of the dependencies as latest – and they will come from the CI feed as pre release RC2 builds.

My project.json is shown below. The application is called Reusable.WebApp and it references a class library, created in the same solution, called Reusable.Components.
We are also referencing Microsoft.AspNet.FileProviders.Embedded package, but more on that later.

Our reusable view component is going to something very simple – something that we already built in the old post. Of course no one wants to read old posts, so here is the C# code:

And the corresponidng Razor view, located under /Views/Shared/Components/PromotedProducts/Default.cshtml.

As mentioned, the difference is that instead of adding all that code into an ASP.NET Web Application, we are actually going to add it to a class library instead (that Reusable.Components project I mentioned earlier).
This class library needs to reference Microsoft.AspNet.Mvc package in the project.json in order to be able to contain a class inherting from ViewComponent, otherwise it wouldn’t compile, but that’s about it – it’s not a web project by any means.

Now, in order for the Razor views to be embedded as resources inside this library, we need an additional node in the project.json, called resources where we’ll specify the path to our library-specific views. This is shown in the next listing, illustrating the project.json of that class library:

Note that since we are using the CI feed, and every package involved is latest and greatest, the target framework moniker needs to be dotnet5.5 not dotnet5.4 anymore, but that’s just a detail.

Finally, to stitch it all together we need to instruct ASP.NET MVC 6 to use our external components by adding an EmbeddedFileProvider, pointing to our Reusable.Components class library as one of the available file providers in the web application. This is done at application startup, inside the ConfigureServices method of the Startup class.

Because the FileProviders on the RazorViewEngineOptions is now (in RC2) a collection, we can now inject an extra provider without having to worry about losing the default PhysicalFileProvider.

And that’s about it. You can now add the view component (a call to @await Component.InvokeAsync(“PromotedProducts”)) to any page in your application and use as if it was locally present inside the web app. There are surely plenty of great uses cases of being able to package reusable components this way and use them in various web applications.

As a reminder, all of the source code for this article is available at Github


You can also use this approach in ASP.NET MVC 6 RC1 if you just pull in a CI version (so RC2-compatible) of Microsoft.AspNet.FileProviders.Composite package. It will contain a CompositeFileProvider, which will let you to bundle together the default file provider (PhysicalFileProvider) and an external one such as an EmbeddedFileProvider pointing to your class library with reusabel components. Then you can simply set this instance of CompositeFileProvider on the FileProvider property of RazorViewEngineOptions. The reason for this is that – as mentioned already – MVC 6 RC1 had only a single file provider, while MVC 6 RC2 allows multiple – hence the difference in the apporach.

Be Sociable, Share!

  • nelsonlaquet

    Awesome, thanks!

    I do want to ask one small (mostly unrelated) thing though, that I’ve seen around lately but haven’t bothered asking on SO because it sounds like a silly question…

    On this line:

    You use “typeof(…).GetTypeInfo().Assembly” instead of “typeof(…).Assembly”. All it seems to do based off of the decompiled source is call ((IReflectableType)type).GetTypeInfo(). The TypeInfo class implements this interface, and its implementation of GetTypeInfo is simply a “return this;”. Since typeof(…) seems to return a TypeInfo anyway (casted to a Type), this seems redundant.

    There shouldn’t be a difference (statically) between Type.Assembly and TypeInfo.Assembly. Is the static conversion between Type and TypeInfo necessary, or there due to some upcoming API changes to System.Reflection?

  • Søren Reinke

    Please make your site printable.

    We are still people who prefer to lay in our bed or couch, and read a piece of paper :)

  • Alexander Pino

    Hi Filip, would these new changes also allow me to pick/assign Controllers, Views and … Models dynamically? I’d like to be able to select and assign these controllers, views, routes and basically everything … for a CMS. No attributes, no naming conventions, everything dynamic and configurable at run-time. Kind of like Sitecore does. Currently using RC1 I’m finding it hard to intercept and wrap basically everything.

  • Harry McIntyre


    I maintain a VPP project called EmbeddedResourceVirtualPathProvider, and have been wondering about whether or not I’ll need to write a vnext/MVC6/core version. Hopefully not!

    There are a couple of features in my project

    – handles resources in subfolders (can’t tell from the docs if the EmbeddedFileProvider does?)
    – can serve from source files if available to allow live editing (is this irrelevant with the new live compiler)

    Do you happen to know if theses features are covered?

  • Alexsandro

    Did already think to use those dlls dynamically?

    I’m looking for that, implement a possible muit tenant application.

  • Darrell Tunnell

    Good post!
    One thing to note, this doesn’t appear work if you remove the project / assembly reference to your VC component, it seems like the project reference is mandatory, which is useless for extensibility scenarios common of many CMS systems. Repro here:

  • Grahame Horner

    I’m wondering if a CompositeFileProvider that uses Reflection to dynamically load/aggregate registered IFileProvider implementations would be a good idea? and what sort of performance impact this may have with a large number of IFileProviders