ASP. NET Core, asp. netcore

Source: Internet
Author: User

ASP. NET Core, asp. netcore
Overview

Large Web applications require better organization than small Web applications. In large applications, the default organizational structure used by ASP. net mvc (and Core MVC) becomes your burden. You can use two simple techniques to update your organization and follow up on growing applications in a timely manner.

The Model-View-Controller (MVC) mode is quite mature, even in Microsoft ASP. NET space. The first version of ASP. net mvc was launched in 2009, and the ASP. NET Core MVC platform was fully launched in the early summer of this year. So far, with ASP. net mvc improvement, the default project structure has remained unchanged: "controller" and "View" folders, usually with "model" (or may be ViewModels) folders. In fact, if you create an ASP. NET Core application, you will see that these folders are created by default templates, suchFigure 1.

Figure 1 default ASP. NET Core Web Application Template structure

This organizational structure has many advantages. It is very familiar; if you have been using ASP. net mvc projects for the past few years, you will soon recognize it. It is well organized; if you are looking for a controller or view, you will know where to start. When you start a new project, the organizational structure runs well because there are not many files. However, as the project grows, the friction between locating the desired controller or viewing files in the increasing number of files and folders in these layers also increases.

To understand what I mean, imagine that you organize your computer files in the same structure. You do not have separate folders for different projects or work types, but only directories fully organized by file types. There may be folders for text documents, PDF files, images, and workbooks. When you execute special tasks that contain multiple types of documents, you will need to jump back and forth between different folders and many files in each folder (these files are not related to the current task). This is the way in which the MVC application functions are organized by default.

The problem with this method is that file groups that are organized by type rather than by purpose often lack aggregation. Aggregation refers to the degree to which elements of a module belong together. In a typical ASP. net mvc project, a given controller references one or more related views (in a folder corresponding to the Controller name ). Both controllers and views refer to one or more viewmodels related to the Controller's responsibilities. However, the ViewModel type or view is rarely used by multiple controller types (and in general, the domain model or persistent model is moved to its own separate project ).

Sample project

Consider a simple project (tasks that manage four loose and related application concepts): Ninjas, Plants, Pirates, and Zombies. The actual example only allows you to list, view, and add these concepts. However, imagine that there are other complexities that involve more views here. The default organizational structure of the project should look similarFigure 2.

 

Figure 2 sample projects that use the default Organization

To use some new features that contain Pirates, You need to navigate to controller and find PiratesController, and then navigate from view to Pirates and corresponding view files in turn. Although there are only five controllers, you can see that there are many folder navigation that move up and down. This problem is more serious when the project root contains more folders, because controllers and views are not arranged in alphabetical order (other folders are usually placed between the two folders in the folder list ).

An alternative method for organizing files by file type is to organize files by application execution. Your project will organize folders around functional or organizational areas to replace folders organized by controllers, models, and views. When you operate bugs or functions related to a specific function of an application, you need to open a few folders because the related files may be stored together. You can perform this operation in multiple ways, including using the built-in Areas function for functional folders and using your own conventions.

How to view files using ASP. NET Core MVC

We need to take some time to talk about how ASP. NET Core MVC works with standard files built in with the application. Most of the files involved in the application server will be written in some. NET languages by category. As long as they can be compiled and referenced by applications, these code files can be stored anywhere on the disk. Specifically, controller files do not need to be stored in any specific folder. Various model classes (such as the domain model, view model, and persistent model) are the same. They can be easily stored in a separate project of the ASP. net mvc Core project. You can sort and rearrange most of the code files in the application in any way you want.

However, the "View" file is different. The "View" file is a content file. They are irrelevant to the locations stored by the Controller class of the application, but it is important that MVC know where to find them. Compared with the default "View" folder, Areas provides built-in support for locating views in different regions. You can also customize the way MVC determines the view position.

Use Areas to organize MVC Projects

Areas allows you to organize independent modules in ASP. net mvc applications. Each Area has a folder structure that simulates the project root conventions. Therefore, your MVC application should have the same root folder conventions and additional folders called Areas, which contain the folders of each part of an application, it includes the "controller" and "View" folders (as needed, it may also include the "model" or "ViewModels" folder ).

Areas has powerful features: allows you to split a large application into separate and logically reasonable sub-applications. For example, a controller can have the same name across regions. In fact, it is common to have a HomeController class in each region of an application.

To add Areas support for ASP. net mvc Core projects, you only need to create a new root-level folder named "Areas. In this folder, create a folder for each part of the application you want to organize in the Area. Then, add a new folder for controller and view in the folder.

Therefore, your controller file should be located:

/Areas/[area name]/Controllers/[controller name].cs

Your controller must have the Area attribute that applies to it so that the framework knows that they belong to a specific region:

namespace WithAreas.Areas.Ninjas.Controllers{  [Area("Ninjas")]  public class HomeController : Controller

Then, your view should be located:

/Areas/[area name]/Views/[controller name]/[action name].cshtml

Any link to the view that has been moved to the region should be updated. If you are using the help program, you can specify the region name as part of the help program. For example,

<a asp-area="Ninjas" asp-controller="Home" asp-action="Index">Ninjas</a>

The asp-area attribute can be omitted for links between views in the same region.

The last thing you need to do for the regions that support your application is to update the default routing rules of the applications in Startup. cs in the "configuration" method:

app.UseMvc(routes =>{  // Areas support  routes.MapRoute(    name: "areaRoute",    template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");  routes.MapRoute(    name: "default",    template: "{controller=Home}/{action=Index}/{id?}");});

For example, you can use Areas to manage various Ninjas, Pirates, and other sample applications to implement the project organization structure, as shown in figureFigure 3.

 

Figure 3 use Areas to organize ASP. NET Core projects

 

Compared with the default conventions, the Areas function improves each logical part of an application by providing separate folders. Areas is a built-in function in ASP. NET Core MVC. It requires minimal settings. If you have not used them, remember that they are a simple method to combine the relevant parts of your application and separate them from the rest of the application.

However, the folder in the Areas organization is still overloaded. You can see this in the required vertical space, which shows the relatively small number of files in the Areas folder. If you do not have many controllers in each region and you do not have many views in each controller, the troubles caused by the folder above are almost the same as the default conventions.

Fortunately, you can easily create your own conventions.

Functional folders in ASP. NET Core MVC

In addition to the default folder conventions or built-in Areas functions, the most popular way to organize MVC projects is to use each function file. This is especially true for teams that have already adopted delivery functionality in vertical segments (see http://deviq.com/vertical-slices/) because most of the user interface focus in vertical segments can exist in any functional folder.

When you organize your project through a function (rather than a file type), there is usually a root folder (such as a "function") with subfolders for each function. This is very similar to the areas method of the Organization. However, in each function folder, you will include all the required controllers, views, and ViewModel types. In most applications, this results in 5 to 15 projects in the folder, all of which are closely related. The entire content of the function folder can be stored in Solution Explorer for viewing. You canFigure 4See the Organization example for this sample project.

Figure 4 Functional folder Organization

Note that even the root-level "controller" and "View" folders are eliminated. Now, the homepage of an application is located in its own functional folder named "Homepage", and shared files (such as _ Layout. cshtml) are also located in the "shared" folder in the "functions" folder. The organizational structure of this project is highly scalable, allowing developers to focus on a specific part of an application in fewer folders.

In this example, the difference from the use of Areas is that other routes and attributes of the controller are not required (however, note that, the Controller name must be unique among functions in this implementation ). To support this organization, you need to customize IViewLocationExpander and IControllerModelConvention. Use the two with custom ViewLocationFormats to configure MVC in your "Startup" class.

For a given controller, it is useful to know what functions it is associated. Areas achieves this by using attributes, and this method uses conventions. The Convention sets the Controller to be in The namespace named "function", and the next item in the namespace layer after "function" is the function name. This name is added to the attribute (available during view position), as shown in figureFigure 5.

public class FeatureConvention: IControllerModelConvention{  public void Apply(ControllerModel controller)  {    controller.Properties.Add("feature",       GetFeatureName(controller.ControllerType));  }  private string GetFeatureName(TypeInfo controllerType)  {    string[] tokens = controllerType.FullName.Split('.');    if (!tokens.Any(t => t == "Features")) return "";    string featureName = tokens      .SkipWhile(t => !t.Equals("features",        StringComparison.CurrentCultureIgnoreCase))      .Skip(1)      .Take(1)      .FirstOrDefault();    return featureName;  }}

Figure 5 FeatureConvention: IControllerModelConvention

 

When adding MVC in startup, add this convention as part of MvcOptions:

services.AddMvc(o => o.Conventions.Add(new FeatureConvention()));

To replace the normal View location logic used by MVC with a function-based convention, you can clear the View LocationFormats used by MVC and replace it with your own list. This operation is executed as part of the AddMvc call, as shown in figureFigure 6.

services.AddMvc(o => o.Conventions.Add(new FeatureConvention()))  .AddRazorOptions(options =>  {    // {0} - Action Name    // {1} - Controller Name    // {2} - Area Name    // {3} - Feature Name    // Replace normal view location entirely    options.ViewLocationFormats.Clear();    options.ViewLocationFormats.Add("/Features/{3}/{1}/{0}.cshtml");    options.ViewLocationFormats.Add("/Features/{3}/{0}.cshtml");    options.ViewLocationFormats.Add("/Features/Shared/{0}.cshtml");    options.ViewLocationExpanders.Add(new FeatureViewLocationExpander());  }

Figure 6 replace the normal view location logic used by MVC

By default, these format strings contain the placeholder for the operation ("{0}"), controller ("{1}"), and region ("{2 }"). The method adds 4th features ("{3 }").

The view location format should support views with the same name but used by different controllers in the function. For example, it is common to have multiple controllers in the function and multiple controllers have an index method. This function is supported by searching for views in a folder that matches the Controller name. Therefore, NinjasController. Index and SwordsController. Index should be located in their respective/Features/Ninjas/Index. cshtml and/Features/Ninjas/Swords/Index. cshtml views (seeFigure 7).

Figure 7 multiple controllers for each function

Note that this function is optional-if your function does not need to distinguish between views (for example, because the function only has one controller), you only need to place the view directly in the function folder. Similarly, you are more willing to use the file prefix than folders, you only need to easily adjust the format string from "{3}/{1}" to "{3} {1}" for use, thus generating the View File name, such as NinjasIndex. cshtml and SwordsIndex. cshtml.

Shared views are supported in the root and shared subfolders of the functional folder.

The IViewLocationExpander interface provides an ExpandViewLocations method (the framework uses this method to identify folders containing views ). These folders will be searched when the operation returns to the view. This method only requires ViewLocation-Expander to replace the "{3}" mark with the controller function name (specified by FeatureConvention mentioned earlier ):

public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context,  IEnumerable<string> viewLocations){  // Error checking removed for brevity  var controllerActionDescriptor =    context.ActionContext.ActionDescriptor as ControllerActionDescriptor;  string featureName = controllerActionDescriptor.Properties["feature"] as string;  foreach (var location in viewLocations)  {    yield return location.Replace("{3}", featureName);  }}

To correctly support publishing, you also need to update the publishOptions of project. json to include the "function" folder:

"publishOptions": {  "include": [    "wwwroot",    "Views",    "Areas/**/*.cshtml",    "Features/**/*.cshtml",    "appsettings.json",    "web.config"  ]},

You have full control over the new conventions for using folders named "function" and the folder organization mode. By modifying the View ­ LocationFormats set (or FeatureViewLocationExpander type behavior), you can fully control the position of the View of your application. This is the only operation required to reorganize your files, because the Controller type is found in any folder.

 

Parallel function folder

If you want to try the functional folder in parallel with the default MVC Area and view conventions, you only need a small modification to implement this function. Insert the function format into the starting position of the List to clear ViewLocationFormats (note that the order is reversed ):

options.ViewLocationFormats.Insert(0, "/Features/Shared/{0}.cshtml");options.ViewLocationFormats.Insert(0, "/Features/{3}/{0}.cshtml");options.ViewLocationFormats.Insert(0, "/Features/{3}/{1}/{0}.cshtml");

To support the function of combining regions, you can also modify the AreaViewLocationFormats set:

options.AreaViewLocationFormats.Insert(0, "/Areas/{2}/Features/Shared/{0}.cshtml");options.AreaViewLocationFormats.Insert(0, "/Areas/{2}/Features/{3}/{0}.cshtml");options.AreaViewLocationFormats.Insert(0, "/Areas/{2}/Features/{3}/{1}/{0}.cshtml");
How to deal with models?

Readers with a keen eye will notice that I have not moved my model type into a functional folder (or Areas ). In this example, I have no independent ViewModel type, because the model I am using is extremely simple. In actual applications, the complexity of your domain or persistence model may exceed the complexity required by your view, which will be defined by itself in a separate project. Your MVC application may define the ViewModel type that only contains the data required for the given view, and optimize the display (or used by the client's API requests ). There is no doubt that these ViewModel types should be placed in the functional folders they are used (these types should be shared between functions is rare ).

Summary

The example includes three versions of the NinjaPiratePlant-Zombie organizer application and supports adding and viewing each data type. Download the sample (or view the sample on GitHub) and think about how each method runs in the context of your current application. Add the Area or functional folder to a large application you are using and compare it with using a file-based top-level folder, are you more willing to use the function subdivision as the top-level organization of the folder structure of your application.

The source code for this example can be obtained through the https://github.com/smallprogram/OrganizingAspNetCore.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.