"Feature Folders" structure in ASP.NET MVC

Structuring your files around business concerns is a more natural way of handling projects than structuring them around technical concerns. The Separation of Concerns is applied in both approaches, but not both of them give the same desired clarity and ease for developers. This blog post focuses on organizing MVC projects around feature folders, which represent the business concerns.

Most of the time developers make modifications related to a single feature (e.g. adding new fields, changing business rules, adding validation...). Structuring folders around interrelated files can make modification process simpler. The common MVC folder structure violates the rule of "Files that change together should be structured together". Structuring by business concerns embraces this very important rule.

Files that change together should be structured together.

Horizontal (Technical) vs. Vertical (Business) Folder Structure

On the left side, you can see the common MVC structure. On the right side, you can see the feature folders structure of the very same project.

Some ALT text

When you see this in your IDE (e.g. in Visual Studio), the distinction between the files is even greater, given that there is accompanied file type icon shown beside the filename.

Now, imagine you scale in amount of features, in addition to the standard N-Layer stuff like repositories, services, handlers, DTOs, etc... You will soon notice that things are starting to get messy in the technical folders organization. In the feature folders organization, each feature can scale on its own, thus much easier to manage.

Food for thought:

  • What if we put our CSS and JavaScript files also in these feature folders?
  • What if one feature folder becomes so demanding on the UI that needs to be a full SPA view/module - can we structure it to use Angular?
  • Can we develop one feature UI in Angular, another one in React, all other in classic server-side MVC, and stay sane with our overall project structure?

Example of single feature evolved as Angular application/module:

Features
    ...
    ShoppingCart
        Components
            CartComponent.js
            CartComponent.css
            PaymentComponent.js
            PaymentComponent.css
            CartContainer.js
        App.js
        App.css
        Index.cshtml
        ShoppingCartController.cs
    ...

Benefits of using Feature Folders (over technical folder structure)

Structuring your files by features (business concerns) makes things easier to find and manage.

  • You don't step over each other toes with your peers, thus, avoid spending time on fixing merge conflicts.
  • You can scale and modify each feature on its own, independently from other features and even use different UI technology.
  • You immediately understand what an application does and where to find necessary files for your given requirement.
  • You can easily reuse similar features across projects by simply copying just a single folder.
  • Time spent on navigation through Solution Explorer to locate interdependent files is drastically reduced since they are all in a single folder.
  • You can reason much easier about each feature just by looking in a single (feature) folder.

Implementing Feature Folders in ASP.NET MVC 5

To make this work in ASP.NET MVC 5, we should inherit the RazorViewEngine and change the view location parts to ones that fit our new structure.

public class FeatureFoldersRazorViewEngine : RazorViewEngine
{
    public FeatureFoldersRazorViewEngine()
    {
        var featureFolderViewLocationFormats = new[]
        {
            "~/Features/{1}/{0}.cshtml",
            "~/Features/{1}/{0}.vbhtml",
            "~/Features/Shared/{0}.cshtml",
            "~/Features/Shared/{0}.vbhtml",
        };

        ViewLocationFormats = featureFolderViewLocationFormats;
        MasterLocationFormats = featureFolderViewLocationFormats;
        PartialViewLocationFormats = featureFolderViewLocationFormats;
    }
}

Next, we have to add our newly created FeatureFoldersRazorViewEngine in our application.

public class Global : HttpApplication
{
    void Application_Start(object sender, EventArgs e)
    {
        // ...
        ViewEngines.Engines.Clear();
        ViewEngines.Engines.Add(new FeatureFoldersRazorViewEngine());
    }
}

Summary

Structuring our MVC projects following feature folders approach increases the productivity of our dev teams.

At HASELT, we have been using feature folders project structure on over dozens of projects for over a year, and due to the high success and productivity boost, it became our default project structure on the presentation layer.

Share this article

Stay updated with HASELT by signing up for our newsletter

Don't worry, we hate spam too!

Keep reading

HASELT list of 10 book recommendations about software development

HASELT list of 10 book recommendations about software development

Here is a list of 10 book suggestions, shared in the past few months under the hashtag #bookrecommendation, now we are making a list of 10 books about…

Read more
2017 HASELT Internship insights

2017 HASELT Internship insights

Since we are somewhere in-between the beginning and the end of our 2017 Internship Program, we are excited to share some insights from our work and progress…

Read more