Что делают директивы @using и @namespace в файле Razor _ViewImports.cshtml?
Вот краткая версия:
@namespace
дает каждому *.cshtml
файлу пространство имен, которое адаптируется к его каталогу
@using
предоставляет каждому *.cshtml
файлу доступ к типам, которые находятся вне его пространства имен
- все файлы
.cshtml
в каталоге и подкаталогах _ViewImport затронуты
Что такое пространство имен C #?
A namespace
создает область. Внутри области имена типов должны быть уникальными.
Изнутри пространства имен файлы имеют безусловный доступ ко всем типам в пространстве имен. Из-за пределов пространства имен файлы могут получать доступ только к тем типам с полным именем, полным пространства имен (или с помощью директивы using
).
Существуют пространства имен для предотвращения конфликтов имен: два типа могут иметь одно и то же имя, если эти имена находятся в разных пространствах имен.
* +1039 * Пример:
namespace Computers {
// the name Apple must be unique within its namespace
// from outside its namespace it is Computers.Apple
public class Apple {}
}
namespace Garden {
public class Apple {
// we access Apple from another namespace via its full name
public void UseComputer(Computers.Apple appleComputer) { }
}
}
Что такое директива C # using?
Использование полного имени типа может быть неудобным. Когда коллизий именования не существует, директива using
предоставляет удобный способ доступа к типу из другого пространства имен - без необходимости уточнять имя типа.
using Computers;
namespace TechnologyStore {
// `using Computer` lets us access Apple without qualifying it
public class SellComputer(Apple appleComputer) { }
}
Как @namespace
и @using
работают в * .cshtml файле?
Файл * .cshtml также имеет пространство имен и тип. Мы можем увидеть это, если перетащим следующий код в Razor Page или View.
// Pages/Index.cshtml
@page
<p>@this.GetType().Namespace</p> // AspNetCore
<p>@this.GetType().Name</p> // Pages_Index
// Pages/Foo/Index.cshtml
@page
<p>@this.GetType().Namespace</p> // AspNetCore
<p>@this.GetType().Name</p> // Pages_Foo_Index
Пространством имен по умолчанию для файла *.cshtml
является AspNetCore
. Это проблема, когда @model находится в каком-то пользовательском пространстве имен. Если @model
находится в MyCustomNamespace
, то мы должны сделать некоторую работу для доступа к нему:
// Pages/Index.cshtml
@page
@namespace MyCustomNamespace
@model IndexModel
<p>@this.GetType().Namespace</p> // MyCustomNamespace
<p>@this.GetType().Name</p> // Pages_Index
Это не слишком много работы; но если мы сохраняем наши пространства имен выровненными с нашими структурами каталогов, и если мы перемещаем файл *.cshtml
, то нам нужно обновить оператор @namespace
.
// Pages/Foo/Index.cshtml
@page
@namespace MyCustomNamespace.Foo
@model IndexModel
<p>@this.GetType().Namespace</p> // MyCustomNamespace.Foo
<p>@this.GetType().Name</p> // Pages_Foo_Index
Теперь файл *.cshtml
имеет то же пространство имен, что и @model
, и тем самым получает к нему доступ.
В приведенном выше примере, чтобы получить доступ к @model
, мы могли бы использовать директиву @using
вместо директивы @namespace
.
Как @namespace
работает в файле _ViewImports.cshtml?
Наличие @namespace
или @using
для каждого файла создает проблему обслуживания, когда мы реорганизуем нашу структуру каталогов. Когда мы помещаем index.cshtml
в каталог Foo
, его @namespace
не меняется автоматически - нам нужно было помнить, чтобы изменить его вручную. Это может быть проблемой, если мы используем инструменты анализа кода, чтобы наши пространства имен *.cs
были выровнены с их каталогами.
Здесь @namespace
в _ViewImports
становится удобным. Он автоматически выравнивает пространства имен файлов * .cshtml с их каталогами.
// Pages/_ViewImports
@namespace MyCustomNamespace
// Pages/Index.cshtml
@page
<p>@this.GetType().Namespace</p> // MyCustomNamespace
<p>@this.GetType().Name</p> // Pages_Index
// Pages/Foo/Index.cshtml
@page
<p>@this.GetType().Namespace</p> // MyCustomNamespace.Foo <- adapts to the directory
<p>@this.GetType().Name</p> // Pages_Foo_Index
Мало того, что каждый файл получает пространство имен, но каждое пространство имен адаптируется к каталогу его файла .
Смотри также
Мы можем прочитать об обосновании существования @namespace
здесь: https://github.com/aspnet/Razor/issues/1159