(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Использование провайдеров компиляции в Asp.net

Источник: realcoding

В Asp.net любая интернет-страница представляется в виде двух файлов: *.aspx и *.aspx.cs. В *.aspx-файлах содержится html-подобная разметка самой страницы, а в *.aspx.cs-файлах код на языке C#, который представлен в виде отдельного класса. В разметку страницы можно добавлять серверные элементы управления, например тегом <asp: Button ID="MyButton" runat="server" />.

Причём с каждым таким объявлением будет связана переменная, то есть в нашем случае мы получим доступ к переменной типа Button и именем MyButton, хотя на первый взгляд эта переменная нигде не объявлена. (Хотя в первой версии Asp.net объявление переменных вставлялись в тот же файл.)

На самом деле это не так. Класс, описаный в *.aspx.cs-файле является частичным (он помечен модификатором partial), одна его часть описана в *.aspx.cs-файле, а вторая находится во временном файле, который генерируется на основании просмотра *.aspx-файла. Генерацией этого временного файла как раз и занимается провайдер компиляции.

Пишем провайдер компиляции

1. Определимся, что будет делать провайдер компиляции.

Чтобы особо не мудрить, пусть он выполняет преобразование xml-файла вида:

 

  1. <classes>
  2.    <class name="С1">
  3.       <property type="int" name="x1" value="17" />
  4.       <property type="string" name="x2" value="Hello, World!" />
  5.    </class>
  6.    <class name="С2">
  7.       <property type="int" name="x1" value="-5" />
  8.       <property type="string" name="x2" value="Это строка!" />
  9.    </class>
  10. </classes>
* This source code was highlighted with Source Code Highlighter.

в статический класс, содержащий константы.

2. Создадим новый проект. В качестве типа проекта выберем "Class Library", назовём его "MyLib".

3. Все провайдеры компиляции являются производными от класса "System.Web.Compilation.BuildProvider", поэтом добавим ссылку на сборку "System.Web" и используемые пространства имён.

Конструктор класса ничего не выполняет, а вот метод "GenerateCode" нам потребуется переопределить. В итоге должно получиться следующее:

 

  1. using System;
  2. using System.Web.Compilation;
  3. using System.Xml;
  4. using System.IO;
  5. using System.Web.Hosting;
  6.  
  7. namespace MyLib
  8. {
  9.   public class MyBP: BuildProvider
  10.   {
  11.     public MyBP() { }
  12.  
  13.     public override void GenerateCode(AssemblyBuilder assemblyBuilder)
  14.     {
  15.       //В переменную writer будем записывать генерируемый код
  16.       using (TextWriter writer = assemblyBuilder.CreateCodeFile(this))
  17.       {
  18.         //Создаём xml-документ используя путь к анализируемому файлу
  19.         XmlDocument xml = new XmlDocument();
  20.         xml.Load(VirtualPathProvider.OpenFile(base.VirtualPath));
  21.  
  22.         //Получаем все классы
  23.         XmlNodeList classes = xml.GetElementsByTagName("class");
  24.         foreach (XmlNode _class in classes)
  25.         {
  26.           //Получаем название класса
  27.           string cName = _class.Attributes["name"].Value;
  28.           if (cName == null // cName.Length == 0) continue;
  29.  
  30.           //Получаем поля класса
  31.           string cProperties = "";
  32.  
  33.           //Получаем все поля
  34.           XmlNodeList properties = _class.ChildNodes;
  35.           foreach (XmlNode property in properties)
  36.           {
  37.             if (property.Name != "property") continue;
  38.  
  39.             //Получаем тип поля
  40.             string pType = property.Attributes["type"].Value;
  41.             if (pType == null // pType.Length == 0) continue;
  42.  
  43.             //Получаем название поля
  44.             string pName = property.Attributes["name"].Value;
  45.             if (pName == null // pName.Length == 0) continue;
  46.  
  47.             //Получаем значение поля
  48.             string pValue = property.Attributes["value"].Value;
  49.             if (pValue == null // pValue.Length == 0) continue;
  50.  
  51.             //Если поле имеет строковой тип, берём его в кавычки
  52.             if (pType == "string") pValue = string.Format(""{0}"", pValue);
  53.  
  54.             //Добавляем поле
  55.             cProperties += string.Format(" public const {0} {1} = {2}; ", pType, pName, pValue);
  56.           }
  57.  
  58.           //Добавляем класс
  59.           writer.Write(" public static partial class " + cName + " { " + cProperties + " } ");
  60.         }
  61.       }
  62.     }
  63.   }
  64. }
* This source code was highlighted with Source Code Highlighter.

Компилируем и получаем сборку.

4. Создаём новый сайт (Назовём его MySite). Первое, что нужно сделать, создать папки bin и App_Code. В папку bin скопируем только что созданную библиотеку. Теперь нужно подключить провайдер компиляции. Для этого идём в файл Web.config и в разделе compilation добавляем блок:

 

  1. <buildProviders>
  2.    <add type="MyLib.MyBP, MyLib" extension=".cc" />
  3. </buildProviders>
* This source code was highlighted with Source Code Highlighter.

Это определение говорит, что для файлов с расширением "cc" будет использован провайдер компиляции MyLib.MyBP, который будет взят из сборки MyLib".

5. Создаём файл "my.cc" в папке "App_Code" с xml-кодом, вроде того, что приведён выше. Через некоторое время (обычно секунд десять, когда файл обработается) в любом C#-коде можно будет использовать классы "C1" и "C2" и их константные поля. (Результаты можно увидеть на скриншотах)

6. Скриншоты:

Документ, обрабатываемый провайдером компиляции:

Появились классы "C1" и "C2":

И их поля:

 

Ну и в качестве концовки

Безусловно данный пример не может претендовать на полноценный провайдер компиляции, а показывает только общую идею, в коде я опустил многие проверки, обработку исключений пожертвовал оптимальностью ради сокращения кода.

PS: Я не нашёл способа не помещать провайдер в отдельную сборку, а просто добавить класс в папку App_Code. В данном случае возникает ошибка о невозможности загрузить тип.

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 15.12.2009 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Microsoft 365 Apps for business (corporate)
Microsoft 365 Business Standard (corporate)
Microsoft Windows Professional 10, Электронный ключ
Microsoft 365 Business Basic (corporate)
Microsoft Office 365 Персональный 32-bit/x64. 1 ПК/MAC + 1 Планшет + 1 Телефон. Все языки. Подписка на 1 год.
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Безопасность компьютерных сетей и защита информации
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
Мастерская программиста
Corel DRAW - от идеи до реализации
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100