Asp.net core 学习笔记 ( Area and Feature folder structure 文件结构 )

2017-09-22 

refer : 

https://msdn.microsoft.com/en-us/magazine/mt763233.aspx?f=255&MSPPError=-2147217396

https://scottsauber.com/2016/04/25/feature-folder-structure-in-asp-net-core/

https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/areas

典型的 MVC 结构是像上面这样的, 所有的 controllers, views 独立收藏.

这种结构在项目逐渐复杂后就会变得很难用.

这里介绍另一种结构 

比如我们要开发一个 Web, 一个 AMP 版本, 还要公开一些 API. 

那么我们可能希望结构像上面这样, 大伙分开管理, 但又可以用相同名字的控制器. 

怎么实现呢 ? 

首先要引入 Area 概念, 这个是 core 的新东西. 

从前的 route 匹配只有 controller + action , 现在多了一个 area  

namespace Project.Controllers
{
    [Area("Web")] 
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
    }
}

每个控制器要定义好专属的 Area. 

然后是 startup.cs 

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{ 
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "AMP",
            template: "amp/{controller=Home}/{action=Index}",
            defaults : new { area = "AMP" }
        );
                 
        routes.MapRoute(
            name: "Web",
            template: "{controller=Home}/{action=Index}",
            defaults: new { area = "Web" }
        );
    });
}

Area 的部分说完了. 

另一个重点是 Feature, feature 只是个代名词, 也不是 core 的东西. 

它只是一个寻找 .cshtml 的方法而已. 

core 原生的结构是这样的 : 路由匹配到控制器后, 通过 area + control + action 去 Views 里面寻找 cshtml 

然而现在我们把 Views 给删除了, 所以我们得告诉它新的 location  

在 startup.cs 

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<RazorViewEngineOptions>(options =>
    {
        options.ViewLocationExpanders.Add(new FeatureLocationExpander());
    });
    services.AddMvc();
}

设置新的 location 逻辑 

public class FeatureLocationExpander : IViewLocationExpander
{
    public void PopulateValues(ViewLocationExpanderContext context)
    {
        // Don't need anything here, but required by the interface
    }

    public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
    {
        // {0} - Action Name
        // {1} - Controller Name
        // {2} - Area Name
        return new string[] {
            "/{2}/{1}/{0}.cshtml",
            "/{2}/Shared/{0}.cshtml"
        };
    }
}

以上. 

原文地址:https://www.cnblogs.com/keatkeat/p/7574962.html