(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 Office для дома и учебы 2019 (лицензия ESD)
Microsoft 365 Business Standard (corporate)
Microsoft Office 365 для Дома 32-bit/x64. 5 ПК/Mac + 5 Планшетов + 5 Телефонов. Подписка на 1 год.
Microsoft Office 365 Профессиональный Плюс. Подписка на 1 рабочее место на 1 год
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-технологии
Один день системного администратора
Утиль - лучший бесплатный софт для Windows
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100