-
Notifications
You must be signed in to change notification settings - Fork 219
Add support for @namespace to configure the namespace the generated class is in #1159
Description
The Problem
The classes that are generated by Razor files are placed in a fixed namespace of AspNetCore.
As part of Razor Pages, it is idiomatic to specify the page's model using @model, e.g.:
@* ~/Pages/Index.cshtml *@
@page
@model IndexModelThe class IndexModel is specified in a sibling CS file named for the CSHTML file it applies to, e.g. Index.cshtml.cs
In page-focused layout it's also normal to nest identically named files in sub-folders as the site structure is built up, e.g.
~/
/Pages
_ViewImports.cshtml
Index.cshtml
Index.cshtml.cs <-- namespace App.Pages { public class IndexModel : PageModel {
/Account
Index.cshtml
Index.cshtml.cs <-- namespace App.Pages.Account { public class IndexModel : PageModel {
/Manage
Index.cshtml
Index.cshtml.cs <-- namespace App.Pages.Account.Manage { public class IndexModel : PageModel {
It's also common to have a _ViewImports.cshtml in the pages root to set the default namespace imports for all pages, e.g.:
@using App
@using App.PagesYou might also include subsequent _ViewImports.cshtml files in the sub-folders to import namespaces for types declared in those sub-folders, e.g.:
@using App.Pages.Account.ManageThis results in it being impossible to refer to page models via @model without using the fully qualified class name (including namespace), as there are multiple namespaces imported where the model class name is present. This isn't ideal as it makes it harder to move the page around independently of its content, such that it breaks if you decide to reorganize the layout.
@* ~/Pages/Account/Manage/Index.cshtml *@
@page
@model App.Pages.Account.Manage.IndexModelThe Proposal
Let's introduce support for changing the namespace of the generated view/page class via the @namespace directive. This directive would be set in the _ViewImports.cshtml of new ASP.NET Core projects (via the project templates) to the application's root namespace by default, much like the default @using directives are today.
The directive will take a very similar form to the @using directive, allowing specification of a namespace following white-space after the directive. At design-time it will be projected to the namespace declaration line in the generated file buffer.
@namespace App.PagesOnly a single instance of the @namespace directive is supported, and it can be overridden by more specific _ViewImports.cshtml files (more specific based on folder depth, similar to @model).
The actual namespace used will be the combination of that specified by the closest @namespace directive in a _ViewImports.cshtml flie, combined with the names of the sub-folders down to the folder containing the page (the path). This way, the namespace will typically only need to be set once for the application in the root _ViewImports.cshtml file, e.g.:
~/
/Pages
_ViewImports.cshtml <-- @namespace App.Pages
Index.cshtml <-- generated namespace: App.Pages
Index.cshtml.cs <-- namespace App.Pages { public class IndexModel : PageModel {
/Account
Index.cshtml <-- generated namespace: App.Pages.Account
Index.cshtml.cs <-- namespace App.Pages.Account { public class IndexModel : PageModel {
/Manage
Index.cshtml <-- generated namespace: App.Pages.Account.Manage
Index.cshtml.cs <-- namespace App.Pages.Account.Manage { public class IndexModel : PageModel {
/Custom
_ViewImports.cshtml <-- @namespace Custom
Index.cshtml <-- generated namespace: Custom
Index.cshtml.cs <-- namespace Custom { public class IndexModel : PageModel {
If no @namespace is specified in a view/page's directives (inherited or direct), the existing default namespace AspNetCore will be used.