Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ASP.NET MVC Урок 1-F / ASP.NET MVC Урок D

.pdf
Скачиваний:
39
Добавлен:
09.03.2016
Размер:
421.5 Кб
Скачать

$63 1(7 09& ǻȘȖȒ ' 6FDIIROGLQJ tutorial

ASP*, .NET*

Цель урока. Научиться использовать Scaffolding для создания прототипа проекта. Определяем и фиксируем структуру репозитория. Простая и языковая версия класса. Тестируем использование Scaffolder­а, используем «направляющие» атрибуты. Параметры для Scaffolder­а. Создание управляющих атрибутов. Полный цикл создания и управления объекта в админке.

Scaffolding T4 для Visual Studio 2013 не применимо.

Scaffolding. Начало.

В этом и следующем уроке мы изучим то, что поможет вам в разы быстрее разрабатывать приложения. Начнем издалека. Когда я делал первый сайт, я смотрел, как можно реализовать тот или иной функционал и использовал его у себя в приложении. Потом, когда у меня появился второй проект, я начал функционал улучшать. Я выделил основные моменты и инструменты, которые были описаны в предыдущих уроках. Я начал замечать, что я делаю часто много механичной работы, например:

создать в БД новую таблицу

прокинуть ее в класс DbContext

добавить объявление в интерфейс репозитария

добавить реализацию в SqlRepository

добавить partial­часть класса в папке Proxy

добавить модель данных

объявить mapping

создать контроллер в админке

сделать типичные view для просмотра и редактирования

Итак как это было поистину скучно, я часто ошибался в одном из шагов – и нужно было править банальные ошибки. И я создал сниппеты, но они решали только половину задачи, а вот модель данных, контроллер, index.cshtml, edit.cshtml – это не было решено.

Ивот я прочитал статью Стивена Сандерсона «Scaffold your ASP.NET MVC 3 project with the MvcScaffolding package» и загорелся. Скаффолдинг подходил мне идеально, но он не был написан для моего решения. И я начал изучать. В основе его стоял T4 (Text Template Transformation Toolkit), в шаблонах используется именно этот синтаксис, но для работы дошаблонной логики используется Windows PowerShell. Собственно, с PowerShell мы работаем в

PackageManager Console (ух, как закручено!). Я совсем немного погружусь в Windows PowerShell

и T4, только для того, чтобы создать пару скаффолдеров для работы с проектом.

Итак, что нам изначально необходимо, так это установить PowerGUI для работы с PowerShell. В VS2010 есть много редакторов для PowerShell. Но мы работаем с VS2012 и нам пока так не повезло.

Ок, установили. Переходим к установке редактора для t4 ­ http://t4­editor.tangible­ engineering.com. Тоже пока что единственный редактор для VS2012. Ну что ж – подсветочка есть и ладно.

T4

Далее изучим, что у нас есть. Начнем с T4. Я пользовался этой ссылкой:http://www.olegsych.com/2007/12/text­template­transformation­toolkit/

Создадим новый проект, библиотеку классов LesssonProject.T4. И добавим туда HelloWorld.tt:

Изменим немного:

# WHPSODWH GHEXJ WUXH KRVW6SHFLILF WUXH ! # RXWSXW H[WHQVLRQ FV !

#$VVHPEO\ 1DPH 6\VWHP &RUH ! #$VVHPEO\ 1DPH 6\VWHP :LQGRZV )RUPV ! # LPSRUW QDPHVSDFH 6\VWHP ! # LPSRUW QDPHVSDFH 6\VWHP ,2 ! # LPSRUW QDPHVSDFH 6\VWHP 'LDJQRVWLFV ! # LPSRUW QDPHVSDFH 6\VWHP /LQT ! # LPSRUW QDPHVSDFH 6\VWHP &ROOHFWLRQV !

# LPSRUW QDPHVSDFH 6\VWHP &ROOHFWLRQV *HQHULF !

YDUJUHHWLQJ +HOOR :RUOG !

7KLV LV WKH RXWSXW FRGH IURP \RXU WHPSODWH

\RX RQO\ JHW V\QWD[ KLJKOLJKWLQJ KHUH QRW LQWHOOLVHQVH QDPHVSDFH 0\1DPH6SDFH

^

FODVV 0\*HQHUDWHG&ODVV

^

 

 

VWDWLF YRLG PDLQ VWULQJ>@ DUJV

 

 

^

 

 

 

 

6\VWHP &RQVROH :ULWH/LQH JUHHWLQJ !

 

 

`

 

 

`

 

 

`

 

 

 

 

 

 

 

 

 

 

 

,QVHUW DQ\ WHPSODWH SURFHGXUHV KHUHYRLG IRR^`

!

Ок, и результатом этого будет:

7KLV LV WKH RXWSXW FRGH IURP \RXU WHPSODWH

\RX RQO\ JHW V\QWD[ KLJKOLJKWLQJ KHUH QRW LQWHOOLVHQVH QDPHVSDFH 0\1DPH6SDFH

^

FODVV 0\*HQHUDWHG&ODVV

^

 

 

VWDWLF YRLG PDLQ VWULQJ>@ DUJV

 

 

^

 

 

 

 

6\VWHP &RQVROH :ULWH/LQH+HOOR :RUOG

 

 

`

 

 

`

 

 

`

 

 

 

На самом деле .tt файл преобразуется в код, который создает конкретный класс, наследуемый от TextTransformation. Этот код запускается и генерируется файл­результат. Выглядит примерно так:

# WHPSODWH ODQJXDJH & !

+HOOR :RUOG

Преобразуется в:

SXEOLF FODVV *HQHUDWHG7H[W7UDQVIRUP 0LFURVRIW 9LVXDO6WXGLR 7H[W7HPSODWLQJ 7H[W7UDQVIRUPDWLRQ

^

SXEOLF RYHUULGH VWULQJ 7UDQVIRUP7H[W

^

WKLV:ULWH+HOOR :RUOG

UHWXUQ WKLV*HQHUDWLRQ(QYLURQPHQW 7R6WULQJ

`

`

А итогом будет файл .cs:

+HOOR:RUOG

Изучим блоки и синтаксис задания шаблонов, который очень похож на aspx, только вместо скобок <% %> используется <# #>. Но, так как aspx мы не изучали, то:

Текстовый блок – это любой не программный текст в тексте шаблона (извините за тафтологию):

# WHPSODWHODQJXDJH &!

+HOOR :RUOG

Блок операторов – это любой блок, заключенный в <# #>. Всё что внутри этого, это языковая конструкция, которая задает логику построения текста:

YDUJUHHWLQJ +HOOR :RUOG

!

Блок выражения – это блок, заключенный в <#= #>. Всё, что внутри этого блока, будет приведено к строке и добавлено в текст шаблона:

6\VWHP &RQVROH:ULWH/LQH JUHHWLQJ !

Блок функций – это блок, заключенный в!. Все функции, объявленные в этом блоке, могут быть вызваны в шаблоне. Кроме того, сами функции могут содержать текст шаблона. Директива# WHPSODWH ! – позволяет задать характеристики класса преобразования из шаблона:

# WHPSODWH ODQJXDJH ´& ´! – задает язык класса.

# WHPSODWH GHEXJ ´WUXH´!– позволяет отладить генерацию шаблона.

# WHPSODWH LQKHULWV ´0\7H[W7UDQVIRUPDWLRQ´! – указывает, какой класс должен

быть использован в качестве базового для класса генерации в процедуре генерации файла.

Директива# RXWSXW ! – задает расширение для генерируемого файла:

# RXWSXWH[WHQVLRQ FV !

Директива # LPSRUW ! – добавляет использование в процедуре исполнения заданных namespace. То же самое что и using добавить (но не в результат, а при выполнении генерации текста):

#LPSRUWQDPHVSDFH 6\VWHP &ROOHFWLRQV!

Директива # DVVHPEO\ ! – добавляет объявление сборки. То же самое, что и в

VisualStudio добавить Reference:

#$VVHPEO\ 1DPH 6\VWHP &RUH!

Директива # LQFOXGH ! – добавляет некий другой шаблон в месте объявления. Это как Html.Partial():

#LQFOXGHILOH ,QFOXGHG WW !

Директива# SDUDPHWHU ! — добавляет параметр при формировании шаблона. Но передача его происходит настолько сложно, что пример я приводить не буду. Ссылка По остальному – смотрите по ссылке.

В общем, этих знаний и знаний по Reflection вполне хватит, чтобы сгенерировать нужные нам файлы, но перейдем к проекту MvcScaffolding.

MVCScaffolding

Установим T4Scaffolding:

30! ,QVWDOO3DFNDJH7 6FDIIROGLQJ

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

>7 6FDIIROGLQJ 6FDIIROGHU 'HVFULSWLRQ &UHDWH ,5HSRVLWRU\ LQWHUIDFH@>&PGOHW%LQGLQJ @

SDUDP

>SDUDPHWHU 0DQGDWRU\ WUXH 9DOXH)URP3LSHOLQH%\3URSHUW\1DPH WUXH @>VWULQJ@ 0RGHO7\S

H

>VWULQJ@ 3URMHFW

>VWULQJ@ &RGH/DQJXDJH

>VWULQJ>@@ 7HPSODWH)ROGHUV

>VZLWFK@ )RUFH IDOVH

IRXQG0RGHO7\SH *HW 3URMHFW7\SH 0RGHO7\SH 3URMHFW 3URMHFW %ORFN8L LIIRXQG0RGHO7\SH ^UHWXUQ`

)LQG WKH ,5HSRVLWRU\ LQWHUIDFH RU FUHDWH LW YLD D WHPSODWH LI QRW DOUHDG\ SUHVHQW IRXQG,5HSRVLWRU\7\SH *HW 3URMHFW7\SH ,5HSRVLWRU\ 3URMHFW 3URMHFW$OORZ0XOWLSOH LIIRXQG,5HSRVLWRU\7\SH

^

&UHDWH ,5HSRVLWRU\

RXWSXW3DWK ,5HSRVLWRU\

GHIDXOW1DPHVSDFH *HW 3URMHFW 3URMHFW 3URSHUWLHV ,WHP'HIDXOW1DPHVSDFH9DOXH

$GG 3URMHFW,WHP9LD7HPSODWH RXWSXW3DWK 7HPSODWH ,5HSRVLWRU\7HPSODWH C

0RGHO #^ 1DPHVSDFH GHIDXOW1DPHVSDFH ` C

6XFFHVV0HVVDJH $GGHG ,5HSRVLWRU\ DW ^ `C

7HPSODWH)ROGHUV 7HPSODWH)ROGHUV 3URMHFW 3URMHFW &RGH/DQJXDJH &RGH/DQJXDJH )RUFH )

RUFH

IRXQG,5HSRVLWRU\7\SH *HW 3URMHFW7\SH ,5HSRVLWRU\ 3URMHFW 3URMHFW

`

$GG D QHZ SURSHUW\ RQ WKH 'E&RQWH[W FODVV LIIRXQG,5HSRVLWRU\7\SH ^

SURSHUW\1DPH IRXQG0RGHO7\SH 1DPH

SURSHUW\1DPHV *HW 3OXUDOL]HG:RUG SURSHUW\1DPH

7KLV LV D 'E&RQWH[W VR ZH FDQ IUHHO\ DGG D QHZ SURSHUW\ LI WKHUH LVQ W DOUHDG\ RQH I

RU WKLV PRGHO

$GG &ODVV0HPEHU9LD7HPSODWH 1DPH SURSHUW\1DPH &RGH&ODVV IRXQG,5HSRVLWRU\7\SH 7HPSODWH ,5HSRVLWRU\,WHP7HPSODWH 0RGHO #^

(QWLW\7\SH IRXQG0RGHO7\SH

(QWLW\7\SH1DPH3OXUDOL]HG SURSHUW\1DPHV

` 6XFFHVV0HVVDJH $GGHG SURSHUW\1DPH WR LQWHUIDFH IRXQG,5HSRVLWRU\7\SH )XOO1DP H7HPSODWH)ROGHUV 7HPSODWH)ROGHUV 3URMHFW 3URMHFW &RGH/DQJXDJH &RGH/DQJXDJH

`

UHWXUQ#^

'E&RQWH[W7\SH IRXQG'E&RQWH[W7\SH

`

Потом IRepositoryItemTemplate.cs.t4:

# 7HPSODWH /DQJXDJH & +RVW6SHFLILF 7UXH ,QKHULWV '\QDPLF7UDQVIRUP ! UHJLRQ (QY'7( &RGH7\SH 0RGHO (QWLW\7\SH 1DPH !

,4XHU\DEOH (QY'7( &RGH7\SH 0RGHO (QWLW\7\SH 1DPH !! 0RGHO (QWLW\7\SH1DPH3OXUDOL]HG !

^ JHW `

ERRO&UHDWH (QY'7( &RGH7\SH 0RGHO (QWLW\7\SH 1DPH ! (QY'7( &RGH7\SH 0RGHO (QWLW\7\S H 1DPH ! LQVWDQFH

ERRO8SGDWH (QY'7( &RGH7\SH 0RGHO (QWLW\7\SH 1DPH ! (QY'7( &RGH7\SH 0RGHO (QWLW\7\S H 1DPH ! LQVWDQFH

ERRO5HPRYH (QY'7( &RGH7\SH 0RGHO (QWLW\7\SH 1DPH ! LQW LG (QY'7( &RGH7\SH 0RGHO (QWLW \7\SH 1DPH !

HQGUHJLRQ

ɂ ,5HSRVLWRU\7HPSODWH FV W

# 7HPSODWH /DQJXDJH & +RVW6SHFLILF 7UXH ,QKHULWV '\QDPLF7UDQVIRUP !# 2XWSXW ([WHQVLRQ FV !

XVLQJ6\VWHP

XVLQJ6\VWHP &ROOHFWLRQV *HQHULF

XVLQJ6\VWHP /LQT

XVLQJ6\VWHP :HE

QDPHVSDFH 0RGHO 1DPHVSDFH !

^

SXEOLFLQWHUIDFH ,5HSRVLWRU\

^

,4XHU\DEOH 7! *HW7DEOH 7! ZKHUH 7FODVV

`

`

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

Name

DataType

 

 

UserIDint (foreignKey to User)

Messagenvarchar(140)

AddedDatedatetime

IsReadedbit

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

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

30! 6FDIIROG ,5HSRVLWRU\ 1RWLI\

$GGHG1RWLI\WR LQWHUIDFH/HVVRQ3URMHFW 0RGHO ,5HSRVLWRU\

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

>7 6FDIIROGLQJ 6FDIIROGHU 'HVFULSWLRQ &UHDWH ,5HSRVLWRU\ LQWHUIDFH@>&PGOHW%LQGLQJ @

SDUDP

>SDUDPHWHU 0DQGDWRU\ WUXH 9DOXH)URP3LSHOLQH%\3URSHUW\1DPH WUXH @>VWULQJ@ 0RGHO7\S

H

>VWULQJ@ 3URMHFW

>VWULQJ@ &RGH/DQJXDJH

>VWULQJ>@@ 7HPSODWH)ROGHUV

>VZLWFK@ )RUFH IDOVH

Это структура объявления кода скаффолдера. Особое внимание нужно обратить на 0RGHO7\SH

это имя класса, именно его мы и передаем в команде 6FDIIROG ,5HSRVLWRU\ 1RWLI\. Остальные параметры идут или по умолчанию, как Force, или по умолчанию известны, как Project, CodeLanguage.

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

IRXQG0RGHO7\SH *HW 3URMHFW7\SH 0RGHO7\SH 3URMHFW 3URMHFW %ORFN8L

LIIRXQG0RGHO7\SH ^UHWXUQ`

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

)LQG WKH ,5HSRVLWRU\ LQWHUIDFH RU FUHDWH LW YLD D WHPSODWH LI QRW DOUHDG\ SUHVHQW

IRXQG,5HSRVLWRU\7\SH *HW 3URMHFW7\SH ,5HSRVLWRU\ 3URMHFW 3URMHFW$OORZ0XOWLSOH

LIIRXQG,5HSRVLWRU\7\SH

^

&UHDWH ,5HSRVLWRU\

RXWSXW3DWK ,5HSRVLWRU\

GHIDXOW1DPHVSDFH *HW 3URMHFW 3URMHFW 3URSHUWLHV ,WHP'HIDXOW1DPHVSDFH9DOXH

$GG 3URMHFW,WHP9LD7HPSODWH RXWSXW3DWK 7HPSODWH ,5HSRVLWRU\7HPSODWH C

0RGHO #^ 1DPHVSDFH GHIDXOW1DPHVSDFH ` C

6XFFHVV0HVVDJH $GGHG ,5HSRVLWRU\ DW ^ `C

7HPSODWH)ROGHUV 7HPSODWH)ROGHUV 3URMHFW 3URMHFW &RGH/DQJXDJH &RGH/DQJXDJH )RUFH )

RUFH

IRXQG,5HSRVLWRU\7\SH *HW 3URMHFW7\SH ,5HSRVLWRU\ 3URMHFW 3URMHFW

`

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

0RGHO #^ 1DPHVSDFH GHIDXOW1DPHVSDFH ` C

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

*HW 3URMHFW 3URMHFW 3URSHUWLHV ,WHP'HIDXOW1DPHVSDFH9DOXH

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

QDPHVSDFH 0RGHO 1DPHVSDFH !

Ок, файл создан (или найден) и идем к следующему шагу. Если всё хорошо сгеренировалось (IRXQG,5HSRVLWRU\7\SH), то добавим в этот класс несколько свойств по

шаблону ,5HSRVLWRU\,WHP7HPSODWH с параметрами:

$GG D QHZ SURSHUW\ RQ WKH 'E&RQWH[W FODVV

LIIRXQG,5HSRVLWRU\7\SH ^

SURSHUW\1DPH IRXQG0RGHO7\SH 1DPH

SURSHUW\1DPHV *HW 3OXUDOL]HG:RUG SURSHUW\1DPH

7KLV LV D 'E&RQWH[W VR ZH FDQ IUHHO\ DGG D QHZ SURSHUW\ LI WKHUH LVQ W DOUHDG\ RQH I

RU WKLV PRGHO

$GG &ODVV0HPEHU9LD7HPSODWH 1DPH SURSHUW\1DPH &RGH&ODVV IRXQG,5HSRVLWRU\7\SH 7HPSODWH ,5HSRVLWRU\,WHP7HPSODWH 0RGHO #^

(QWLW\7\SH IRXQG0RGHO7\SH

(QWLW\7\SH1DPH3OXUDOL]HG SURSHUW\1DPHV

` 6XFFHVV0HVVDJH $GGHGSURSHUW\1DPHWR LQWHUIDFHIRXQG,5HSRVLWRU\7\SH )XOO1DP

H 7HPSODWH)ROGHUV 7HPSODWH)ROGHUV 3URMHFW 3URMHFW &RGH/DQJXDJH &RGH/DQJXDJH

`

Параметры:

0RGHO #^

(QWLW\7\SH IRXQG0RGHO7\SH

(QWLW\7\SH1DPH3OXUDOL]HG SURSHUW\1DPHV

`

Кстати, обратите внимание на *HW 3OXUDOL]HG:RUG и какую роль оно сыграло в созданном шаблоне:

,4XHU\DEOH 1RWLI\! 1RWLILHV ^JHW`

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

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

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

FODVV *HW 3URMHFW7\SH +RPH&RQWUROOHU

$GG &ODVV0HPEHU FODVVSXEOLF VWULQJ 0\1HZ6WULQJ)LHOG

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

FODVV *HW 3URMHFW7\SH +RPH&RQWUROOHU

$GG &ODVV0HPEHU9LD7HPSODWH &RGH&ODVV FODVV 7HPSODWH<RXU7HPSODWH1DPH0RGHO #^ 6RPH3DU

Соседние файлы в папке ASP.NET MVC Урок 1-F