Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






MVCScaffolding






Установим T4Scaffolding:

PM> Install-Package T4Scaffolding

Создадим папку CodeTemplates/Scaffolders/IRepository в LessonProject.Model в ней добавим файлы IRepository.ps1 (LessonProject.Model/CodeTemplates/Scaffolders/IRepository/IRepository.ps1):

[T4Scaffolding.Scaffolder(Description = " Create IRepository interface")][CmdletBinding()]

param(

[parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string]$ModelType,

[string]$Project,

[string]$CodeLanguage,

[string[]]$TemplateFolders,

[switch]$Force = $false

)

 

$foundModelType = Get-ProjectType $ModelType -Project $Project -BlockUi

if (! $foundModelType) { return }

 

# Find the IRepository interface, or create it via a template if not already present

$foundIRepositoryType = Get-ProjectType IRepository -Project $Project -AllowMultiple

if(! $foundIRepositoryType)

{

#Create IRepository

$outputPath = " IRepository"

$defaultNamespace = (Get-Project $Project).Properties.Item(" DefaultNamespace").Value

 

Add-ProjectItemViaTemplate $outputPath -Template IRepositoryTemplate `

-Model @{ Namespace = $defaultNamespace } `

-SuccessMessage " Added IRepository at {0}" `

-TemplateFolders $TemplateFolders -Project $Project -CodeLanguage $CodeLanguage -Force: $Force

 

$foundIRepositoryType = Get-ProjectType IRepository -Project $Project

}

 

# Add a new property on the DbContext class

if ($foundIRepositoryType) {

$propertyName = $foundModelType.Name

$propertyNames = Get-PluralizedWord $propertyName

# This *is* a DbContext, so we can freely add a new property if there isn't already one for this model

Add-ClassMemberViaTemplate -Name $propertyName -CodeClass $foundIRepositoryType -Template IRepositoryItemTemplate -Model @{

EntityType = $foundModelType;

EntityTypeNamePluralized = $propertyNames;

} -SuccessMessage " Added '$propertyName' to interface '$($foundIRepositoryType.FullName)'" -TemplateFolders $TemplateFolders -Project $Project -CodeLanguage $CodeLanguage

 

}

 

return @{

DbContextType = $foundDbContextType

}

Потом IRepositoryItemTemplate.cs.t4:

< #@ Template Language=" C#" HostSpecific=" True" Inherits=" DynamicTransform" #>

#region < #= ((EnvDTE.CodeType)Model.EntityType).Name #>

 

IQueryable< < #= ((EnvDTE.CodeType)Model.EntityType).Name #> > < #= Model.EntityTypeNamePluralized #> { get; }

 

bool Create< #= ((EnvDTE.CodeType)Model.EntityType).Name #> (< #= ((EnvDTE.CodeType)Model.EntityType).Name #> instance);

 

bool Update< #= ((EnvDTE.CodeType)Model.EntityType).Name #> (< #= ((EnvDTE.CodeType)Model.EntityType).Name #> instance);

 

bool Remove< #=((EnvDTE.CodeType)Model.EntityType).Name #> (int id< #= ((EnvDTE.CodeType)Model.EntityType).Name #>);

 

#endregion

И IRepositoryTemplate.cs.t4:

< #@ Template Language=" C#" HostSpecific=" True" Inherits=" DynamicTransform" #>

< #@ Output Extension=" cs" #>

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

 

namespace < #= Model.Namespace #>

{

public interface IRepository

{

IQueryable< T> GetTable< T> () where T: class;

}

}


 

Создадим новую таблицу Notify:

Name DataType
ID Int autoincrement
UserID Int (foreignKey to User)
Message Nvarchar(140)
AddedDate datetime
IsReaded bit

 

Перенесем в DbContext (LessonProjectDb.dbml) и сохраняем (ctrl-S):

В Package Manager Console пишем для проекта LessonProject.Model:

PM> Scaffold IRepository Notify

Added 'Notify' to interface 'LessonProject.Model.IRepository'

Ура! Всё работает! Просто, не правда ли? Ничего не ясно? Ок, ладно разберем IRepository.ps1 по порядку:

[T4Scaffolding.Scaffolder(Description = " Create IRepository interface")][CmdletBinding()]

param(

[parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)][string ]$ModelType,

[string]$Project,

[string]$CodeLanguage,

[string[]]$TemplateFolders,

[switch]$Force = $false

)

 

Это структура объявления кода скаффолдера. Особое внимание нужно обратить на $ModelType – это имя класса, именно его мы и передаем в команде Scaffold IRepository Notify. Остальные параметры идут или по умолчанию, как Force, или по умолчанию известны, как Project, CodeLanguage.

Далее мы ищем этот класс (если мы не сохранимся, то искомый класс еще не будет записан и не будет найден):

$foundModelType = Get-ProjectType $ModelType -Project $Project -BlockUi

if (! $foundModelType) { return }

 

Класс найден и мы переходим к следующей части. Найти файл IRepository.cs и если его нет, то создать:

# Find the IRepository interface, or create it via a template if not already present

$foundIRepositoryType = Get-ProjectType IRepository -Project $Project -AllowMultiple

if (! $foundIRepositoryType)

{

#Create IRepository

$outputPath = " IRepository"

$defaultNamespace = (Get-Project $Project).Properties.Item(" DefaultNamespace").Value

 

Add-ProjectItemViaTemplate $outputPath -Template IRepositoryTemplate `

-Model @{ Namespace = $defaultNamespace } `

-SuccessMessage " Added IRepository at {0}" `

-TemplateFolders $TemplateFolders -Project $Project -CodeLanguage $CodeLanguage -Force: $Force

 

$foundIRepositoryType = Get-ProjectType IRepository -Project $Project

}

 

Тут как раз вызывается IRepositoryTemplate.cs.t4 при необходимости, и туда в качестве модели данных (так же, как в View) передается объект

-Model @{ Namespace = $defaultNamespace } `

 

А defaultNamespace был получен из свойства проекта

Get-Project $Project).Properties.Item(" DefaultNamespace").Value

 

В шаблоне мы это используем (CodeTemplates/Scaffolders/IRepository/IRepositoryTemplate.cs.t4):

namespace < #= Model.Namespace #>

Ок, файл создан (или найден) и идем к следующему шагу. Если всё хорошо сгеренировалось ($foundIRepositoryType), то добавим в этот класс несколько свойств по шаблону IRepositoryItemTemplate с параметрами:

 

# Add a new property on the DbContext class

if ($foundIRepositoryType) {

$propertyName = $foundModelType.Name

$propertyNames = Get-PluralizedWord $propertyName

# This *is* a DbContext, so we can freely add a new property if there isn't already one for this model

Add-ClassMemberViaTemplate -Name $propertyName -CodeClass $foundIRepositoryType -Template IRepositoryItemTemplate -Model @{

EntityType = $foundModelType;

EntityTypeNamePluralized = $propertyNames;

} -SuccessMessage " Added '$propertyName' to interface '$($foundIRepositoryType.FullName)'" -TemplateFolders $TemplateFolders -Project $Project -CodeLanguage $CodeLanguage

 

}

Параметры:

-Model @{

EntityType = $foundModelType;

EntityTypeNamePluralized = $propertyNames;

}

Кстати, обратите внимание на Get-PluralizedWord и какую роль оно сыграло в созданном шаблоне:

IQueryable< Notify> Notifies { get; }

Т.е. нормально сформировал множественное число, а не просто прибавлением символа ‘s’, как это было бы в сниппете.

Изучим еще эти T4Scaffolding cmdlet:

· Add-ClassMember – добавляет кусочек кода в существующий класс:

$class = Get-ProjectType HomeController

Add-ClassMember $class " public string MyNewStringField; "

· Add-ClassMemberViaTemplate – добавляем блок кода через шаблон T4:

$class = Get-ProjectType HomeController

Add-ClassMemberViaTemplate -CodeClass $class -Template " YourTemplateName" -Model @{ SomeParam = " SomeValue"; AnotherParam = $false } -TemplateFolders $TemplateFolders

· Add-ProjectItemViaTemplate – добавляем файл (project item) посредством шаблона:

Add-ProjectItemViaTemplate -OutputPath " Some\Folder\MyFile" -Template " YourTemplateName" -Model @{ SomeParam = " SomeValue"; AnotherParam = $false } -TemplateFolders $TemplateFolders

· Get-PluralizedWord / Get-SingularizedWord – получаем множественное/единственное число слова:

$result = Get-PluralizedWord Person # Sets $result to " People"

$result = Get-SingularizedWord People # Sets $result to " Person"


 

· Get-PrimaryKey – получить первичный ключ из модели данных:

$pk = Get-PrimaryKey StockItem

· Get-ProjectFolder – получить класс проектной папки

$folder = Get-ProjectFolder " Views\Shared"

Write-Host " The shared views folder contains $($folder.Count) items"

· Get-ProjectItem – получить файл

$file = Get-ProjectItem " Controllers\HomeController.cs"

$file.Open()

$file.Activate()

· Get-ProjectLanguage – для C# проектов – возвращает cs, для VB проектов возвращает VB

$defaultProjectLanguage = Get-ProjectLanguage

$otherProjectLanguage = Get-ProjectLanguage -Project SomeOtherProjectName

· Get-ProjectType – получит модель класса (EnvDTE.CodeType)

$class = Get-ProjectType HomeController

Add-ClassMember $class " public string MyNewStringField; "

· Get-RelatedEntities – находит все связанные один-ко-многим объекты класса

Get-RelatedEntities Product

· Set-IsCheckedOut – это для работы с source-control. Т.е. если надо checkOut файл какой-то, то это можно выполнить этой командой.

Set-IsCheckedOut " Controllers\HomeController.cs"

Ну что? Чувствуете мощь, которая уже заменит копипастинг в ваших проектах? Но(!) Учтите, что все эти команды были реализованы тоже людьми. И, например, получение первичного ключа будет происходить только, если поле называется ID, а если оно называется PervichniyKlyuch – то, скорее всего, это не сработает. Также сильно не стоит уповать на переводы. Это скаффолдинг, т.е. черновое создание проекта, а не тончайшая настройка. Суть скаффолдинга – это создать, запустить и пойти пить чай, пока программа в автоматическом режиме сделает за вас самую противную механическую рутину.






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.