4

Recently, I read a post where the author describes how we can compile razor views into separate libraries. I would like to ask, is it possible to embed views in libraries without compiling? And then, add custom VirtualPathProvider to read the views.

2 Answers 2

2

You can use my EmbeddedResourceVirtualPathProvider which can be installed via Nuget. It loads resources from referenced assemblies, and also can be set to take dependencies on the source files during development so you can update views without needing a recompile.

Sign up to request clarification or add additional context in comments.

1 Comment

Your library worked for me. Thanks for going through the effort of making a nuget package.
1

In your "shell" MVC project's Global.asax Application_Start register your custom VirtualPathProvider:

HostingEnvironment.RegisterVirtualPathProvider(new CustomVirtualPathProvider());

The actual implementation would be more complex than this because you would likely do some interface-based, reflection, database lookup, etc as a means of pulling metadata, but this would be the general idea (assume you have another MVC project named "AnotherMvcAssembly" with a Foo controller and the Index.cshtml View is marked as an embedded resource:

public class CustomVirtualPathProvider : VirtualPathProvider {
    public override bool DirectoryExists(string virtualDir) {
        return base.DirectoryExists(virtualDir);
    }

    public override bool FileExists(string virtualPath) {
        if (virtualPath == "/Views/Foo/Index.cshtml") {
            return true;
        }
        else {
            return base.FileExists(virtualPath);
        }
    }

    public override System.Web.Caching.CacheDependency GetCacheDependency(string virtualPath, System.Collections.IEnumerable virtualPathDependencies, DateTime utcStart) {
        if (virtualPath == "/Views/Foo/Index.cshtml") {
            Assembly asm = Assembly.Load("AnotherMvcAssembly");
            return new CacheDependency(asm.Location);
        }
        else {
            return base.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
        }
    }

    public override string GetCacheKey(string virtualPath) {
        return base.GetCacheKey(virtualPath);
    }

    public override VirtualDirectory GetDirectory(string virtualDir) {
        return base.GetDirectory(virtualDir);
    }

    public override VirtualFile GetFile(string virtualPath) {
        if (virtualPath == "/Views/Foo/Index.cshtml") {
            return new CustomVirtualFile(virtualPath);
        }
        else {
            return base.GetFile(virtualPath);
        }
    }
}

public class CustomVirtualFile : VirtualFile {
    public CustomVirtualFile(string virtualPath) : base(virtualPath) { }

    public override System.IO.Stream Open() {
        Assembly asm = Assembly.Load("AnotherMvcAssembly");
        return asm.GetManifestResourceStream("AnotherMvcAssembly.Views.Foo.Index.cshtml");
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.