Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

В двадцать втором выпуске рассылки '.Net Собеседник' вы можете прочесть обзор новых компонент и продуктов, разработанных с использованием платформы .Net, получить ссылки на новые технические статьи из Microsoft Knowledge Base,прочесть первод статьи 'Пишем приложения с плагинами на платформе .NET' и узнать как работатьсатрибутами в C#.


Информационный Канал Subscribe.Ru

.Net Собеседник #22

Содержание
  1. От автора
  2. Обзор новостей
  3. Статья выпуска - Пишем приложения с плагинами на платформе .NET
  4. Время кода - Атрибуты в C#
  5. Форумы .Net на www.sql.ru

От автора

Здравствуйте, коллеги!

Хочу представить вам свой новый проект - журнал "Алгоритм". Журнал будет посвящён освещению вопросов программирования на платформе Microsft .Net, программирования и администрирования разлчиных СУБД, распространяться будет только по подписке. Некоторые идеи, реализованные в рассылке, будут более широко и полно реализованы и в журнале. Среди авторов вы наверняка узнаете известные лица с форумов сайта SQL.RU, а может быть и сами захотите написать собственную статью и разместить её в журнале. Так что я с большим удовольствием приглашаю авторов к сотрудничеству. Подписаться на журнал можно будет как через подписные каталоги Украины и России, (со второй половины 2005 г.), так и напрямую (прямо сейчас) перечислив деньги в редакцию, что будет, конечно, дешевле. Так что надеюсь увидеть читателей рассылки среди читателей журнала. Первый номер журнала выйдет в январе-феврале 2005 года. Периодичность издания - 1 раз в 2 месяца, рассылаться будет заказной бандеролью..
Подробнее смотрите на этой страничке.
Что касается рассылки, то она будет существовать и распространяться в прежнем режиме и, надеюсь, ещё не раз вам пригодится.

Желаю приятного чтения.

{К содержанию}

Обзор новостей

  1. C# для разработчиков на Delphi
    Документ в формате pdf, облегчающий разработчикам на Delphi процесс перехода на C#.
  2. Microsoft выложила FlexWiki на SourceForge.NET по лицензии CPL
    Microsoft выпустила FlexWiki, базирующуюся на веб среду для написания заметок и т.п., разработанную на ASP.NET. Это же ПО используется сейчас на Channel 9 Распространяется согласно Microsoft Common Public License.
    FlexWiki – реализация WikiWikiWeb (Очень Быстрый Веб по-гавайски) на ASP.NET , позволяющий быстро разместить информацию в интранет или интернет. Особенности:
    • Простое редактирование текста с использованием простых правил редактирования
    • Уведомления по почте об изменениях в Wiki
    • Поддержка RSS
    • Тема History позволяет просмотреть все версии страницы на протяжении периода её существования
    • Есть поиск по темам
    • Обратные ссылки позволяют вернуться к теме, щёлкнув по её заголовку вверху страницы
    Больше о FlexWiki можно узнать здесь. Закачать можно с SourceForge.NET.
  3. Middsol соединяет CORBA и J2EE с миром .NET.
    Middsol предлагает инструменты для разработки приложений и решений для того, чтобы открыть широко используемые архитектуры J2EE и CORBA для платформы Microsoft .NET.
  4. Вышел компонент для шифрования Warp|Crypto Encryption Component
    Компонент Warp|Crypto Encryption Component позволяет разработчикам легко интегрировать функциональность шифрования в приложения на платформе .Net. Компонент поддерживает 4 алгоритма шифрования и имеет простой интерфейс.
  5. Алекс Хомер сделал обзор по .netCHARTING
    Alex Homer, Microsoft MVP, член сообщества CodeWise Community, группы ASP.NET Insiders и INETA Speaker Bureau сделал обзор набора компонент .netCHARTING Enterprise Edition для ASP.NET.
  6. Разработка пользовательского элемента управления для проверки кредитных карт
    В этой статье рассматривается написание элемента управления, расширяющего механизм валидации ASP.NET и и выполняющего как клиентскую, так и серверную проверки.
  7. Доступно для скачивания ядро БД VistaDB 2.0 (RC3) для .NET
    Ядро БД VistaDB 2.0 (RC3) для .NET теперь доступно для загрузки. VistaDB является альтернативой #1 для БД Jet/Access, MSDE, Xbase и иногда SQL Server, для построения небольших и средних решений. Включает встариваемое ядро размером в 1MB, управляемый провайдер для ADO.NET и компоненты VCL. Пробную версию можно скачать здесь.
  8. Представляем aspNetMime 2.0 – компонент парсинга сообщений в формате Mime
    aspNetMime предлагает возможность разбора сообщений mime, т.е. функциональность нигде более не предлагаемую в таком виде. Некоторые другие особенности и обновления включают: встроенный отлов спама, поддержку асинхронного чёрного списка DNS Blacklist (DNSbl), улучшенную поддержку разбора сообщений формата 8 Bit Mime, конвертацию Html в Plain Text, улучшенное декодирование UTF-7 и т.п.
  9. Представляем aspNetPOP3 v2.0
    Первый компонент, позволяющий привязывать адрес электронной почты к DataGrid и поддерживающий DataBinding, дополнен новыми возможностями: поддержка синхронного и асинхронного чёрного списка DNS Blacklist (DNSbl), улучшенный парсинг формата 8 Bit Mime, более качественную поддержку упавших соединений POP3, автоматическую конвертацию из HTML в Plain Text, а также разбор потоков Mime файлов и текста.
  10. Компонент DualList Drag & Drop
    Поддержка Drag & Drop между двумя компонентами listbox’ами без написания кода. Прочтите статью и скачайте бесплатный компонент (есть исходник на C#).
  11. Вышел Ad Hoc Query Builder 1.0.7 для ASP.net!
    С помощью компонента Ad Hoc Query Builder можно быстро добавить возможность писать запросы на лету для приложений ASP.Net. Можно использовать при построении отчётов, графиков и т.д.
  12. Вышла новая версия провайдера данных MySQLDirect .NET!
    Core Lab объявила о выходе нового провайдера данных MySQLDirect .NET Data Provider v2.50. Особенности в новой версии – пересмотренные, расширенные и переписанные в управляемом коде инструменты, называемые теперь DbTools; добавлен редактор SQL; дизайнеры компонент более тесно интегрированы с DbTools; добавлен новый компонент MySqlDataTable и т.д.
BUGs, FIXes and HOW TO's -
  1. FIX: You receive an exception when you call an extended stored procedure from an ASP.NET Web application

{К содержанию}

Статья выпуска


Пишем приложения с плагинами на платформе .NET

ЯЗЫК: C#
АВТОР: Tim Dawson http://www.divil.co.uk/net/articles/
Код к статье : Демонстрационный проект на VB

ПЕРЕВОД: Чужа В.Ф ака hDrummer

Вступление

Если вы снабдите своё приложение возможностью понимать плагины, то обеспечите себе возможность изменить часть функциональности такого приложения безперекомпиляции, а не путём полной перекомпиляции этого приложения, как это делается обычно. И хотя не все приложения нуждаются в этом, такая возможность все же иногда является нелишней. Это руководство будет наследником того, которое я писал для программистов приложений, написанных на VB6 с использованием COM. По-моему, на .NET это сделать немного легче, чем на COM, и результат получается гораздо более впечатляющим. Например, для отображения интерфейса COM-плагина в диалоговом окне приложения-хоста было похоже на кошмар и требовало немалой изобретательности. Однако в .NET это достаточно тривиальная задача, благодаря архитектуре Windows Forms. Скажу также, что процедуры открытия и исследования DLL в .NET очень похожи.

Архитектура плагинов

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

Пишем интерфейсы

Сначала создадим проект типа Class Library и определим в нём 2 простых интерфейса. Каждый плагин будет иметь свойство с именем плагина и функцией, принимающей 2 целых числа и возвращающих число типа double . Главное приложение будет содержать такой метод, с помощью которого плагин сможет отобразить окно с сообщением в этом приложении. При создании нового проекта типа Class Library, мы по умолчанию получим в нём уже готовый класс. Его нужно удалить и определить интерфейс:

using System;
namespace hDrummer.clInterfaces {
/// <summary>
/// IPlugin
/// </summary>
public interface IPlugin
{
void Initialize(IHost host);
string Name { get; }
double Calculate(int i1, int i2);
}
/// <summary>
/// IHost
/// </summary>
public interface IHost {
void ShowFeedBack(string strFeedBack);
}
}

И наконец установим выходную директорию для этой библиотеки в общий каталог, в который поместим приложение и плагины.

Пишем первый плагин

Поскольку для целей тестирования нам нужен хотя бы один плагин, то и займёмся его написанием. Снова создаем проект типа Class Library, устанавливаем директорию для вывода и создаём ссылку на нашу предыдущую библиотеку. Затем меняем предлагаемый класс следующим образом:

using System;
using hDrummer.clInterfaces;

namespace hDrummer.PluginLibrary
{
/// <summary>
/// Plugin class
/// </summary>
public class PluginSample: clInterfaces.IPlugin
{
private clInterfaces.IHost objHost;
public void Initialize(IHost host)
{
objHost = host;
}
public string Name
{
get
{
return "PluginSample1 - Adds two numbers";
}
}
public double Calculate (int i1, int i2)
{
return i1+i2;
}
}
}

Только что мы создали простой плагин, складывающий два числа. Но хотя мы принимаем ссылку на интерфейс приложения-хоста, однако мы не используем её. Это мы сделаем в следующем плагине.

Пишем приложение-хост

Создадим новый проект типа Windows Application. Первым делом добавим ссылку на только что созданную библиотеку классов и установим выходную директорию в ту же, что и для библиотеки классов (это делается в свойствах проекта-Configuration Properties-Build-Output Path - прим. переводчика.). Существенной частью данной статьи явлется процесс исследования DLL на предмет наличия плагинов, хранение информации о том, какие плагины доступны, инициализация и дальнейшее их использование. Для этого мы создадим класс в файле PluginServices.vb, который инкапсулирует все эти вещи. Для получения списка плагинов используем функцию FindPlugins, которая принимает строку, содержащую каталог для поиска плагинов; строку, содержащую имя интерфейса, по которой мы будем искать классы, реализующие его функциональность. Эта функция перебират все файлы с расширением .dll в указанном каталоге, загружает их с помощью метода Assembly.LoadFrom() и передаёт выполнение другой функции для инспектирования сборки.

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Reflection;
using System.IO;

namespace HostApplication
{
public class Form1 : System.Windows.Forms.Form
{
private System.ComponentModel.Container components = null;

public AvailablePlugins[] FindPlugins(string strPath, string strInterface)
{
ArrayList Plugins = new ArrayList();
string[] strDLLs;
Assembly objDLL;

strDLLs = Directory.GetFileSystemEntries(strPath, "*.dll");
for (int intIndex=0;(intIndex<strDLLs.Length-1);intIndex++)
{
try
{
objDLL = Assembly.LoadFrom(strDLLs[intIndex]);
ExamineAssembly(objDLL, strInterface, Plugins);
}
catch (Exception ex)
{
//ошибка загрузки DLL - мы тут ничего не делаем
}
}
// тут надо посмотреть объявление переменной в VB проекте
//AvailablePlugin Results[Plugins.Count-1];
if (Plugins.Count!=0)
{
Plugins.CopyTo(Results);
return Results;
}
else {return null;}

}
public Form1()
{
InitializeComponent();
}

protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
private void InitializeComponent()
{
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(488, 273);
this.Name = "Form1";
this.Text = "Form1";

}
#endregion
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
} }

Как только все файлы проверены и исследованы, функция возвращает массив типа AvailablePlugin, если что-то найдено, или null, если не найдено ничего. Как видим, функция ExamineAssembly проверяет загруженные сборки. Функция ExamineAssembly перебирает все типы, экспортируемые сборкой, и использует метод GetInterface() для каждого из них, проверяя, не реализует ли он наш интерфейс. Конечно же, в метод передаётся строка, содержащая полностью квалифицированное имя интерфейса. В нашем случае это PluginSample.Interfaces.IPlugin . Если такой тип найден, то ссылка на него добавляется к нашей переменной класса ArrayList, в ней хранится полный путь к DLL и полное имя класса.

private static ExamineAssembly(Assembly objDLL, string strInterface, ArrayList Plugins){
Type objType;
Type objInterface;
AvailablePlugin Plugin;

//Цикл по всем типам в DLL
foreach (objType in objDLL.GetTypes()){
//Смотрим только типы public
if (objType.IsPublic == true) {
//игнорируем абстрактные классы
if ((objType.Attributes And TypeAttributes.Abstract) !=
TypeAttributes.Abstract){
//Смотрим, реализует ли этот тип наш интерфейс
objInterface = objType.GetInterface(strInterface, true);
if (objInterface != null){
Plugin = new AvailablePlugin();
Plugin.AssemblyPath = objDLL.Location;
Plugin.ClassName = objType.FullName;
Plugins.Add(Plugin);
}
}}}}

Наконец, напишем функцию, которая создаст экземпляр необходимого плагина. Она принимает структуру AvailablePlugin и возвращает оbject, который нужно привести к определённому типу в вызывающей процедуре.

public static object CreateInstance(AvailablePlugin Plugin){
Assembly objDLL;
object objPlugin;

try {
//Загружаем dll
objDLL = Assembly.LoadFrom(Plugin.AssemblyPath);

//создаём и возвращаем экземпляр класса
objPlugin = objDLL.CreateInstance(Plugin.ClassName);
}
catch (Exception e){return null;}
return objPlugin;
}}

Вот и всё о файле PluginServices.vb. Всё остальное дотаточно просто. В методе Main мы вызываем метод FindPlugins и заполняем с его помощью список на форме. Пользователь может выбрать какой-то плагин из этого списка, а также имеет возможность выбора двух чисел, запуска плагина и получения результата. Однако, ещё необходимо реализовать класс в приложении-хосте. Класс, который реализует интерфейс IHost и предложит плагинам способ для вызова методов приложения-хоста. В нашем случае такой метод просто отображает диалоговое окно с сообщением.. Я не стану дальше расписывать код приложения, в надежде, что код сам всё расскажет за себя. Однако стоит заметить, что в этом приложении мы всякий раз, при необходимости вычислений, создаём экземпляр плагина, хотя обычно время жизни такого экземпляра должно быть гораздо больше.

Ещё один плагин

Попробуем создать ещё один плагин, перемножающий два числа. Этот плагин будет перемножать два числа. Он также будет использовать интерфейс для отображения результата в диалогов окне. Код находится в папке [Plugin 2]. Вот и всё. Код к данному руководству у вас есть, так что можете использовать файл PluginServices.vb в своих приложениях. В модификациях он не нуждается.
Прим. переводчика: Скачайте проект на VB, чтобы посмотреть код целиком. Ссылка на него - в заголовке статьи.

Вот и всё, удачного программирования!

{К содержанию}

Время кода

Атрибуты в C#

ЯЗЫК: C#
АВТОР: Dickey B. Singh www.road.com
Код к статье : Демонстрация возможностей атрибутов (в конце статьи)

ПЕРЕВОД: Чужа В.Ф ака hDrummer

Есть много способов хранения различной информации с классами, полями и другими членами класса. Категория свойства, транзакционный контекст метода, ключевые слова для расширения языка программирования, использование внешних файлов и т.п. были предложены Андерсом Хейльсбергом, Microsoft. Каждый из этих подходов имеет преимущества перед другим, однако у каждого из них есть свои недостатки для того, чтобы стать действительно универсальным решением.
Во время работы на предыдущего нанимателя, крупную датскую компанию, которая уже не существует (хорошо ребята поработали ;) – прим.переводчика ), мы создавали программную среду для программистов, в которой мы хотели скрыть информаицю об используемой БД (включая информацию о том, какая БД используется, да и не только это) за ООП-слоем. Идея была проста: программисты, использующие нашу среду, должны были иметь возможность быстро создавать приложения на Java, не беспокоясь о спецификациях конкретной СУБД. Также они должны были сохранять метаданные класса в файле XML по одному файлу на каждый Java класс, используя пользовательский интерфейс. Мы разработали репозиторий, использующий XML для хранения метаданных. Среда программирования и репозиторий были написаны на C++. Среда генерировала код создания и изменения таблиц и хранимых процедур для десятков БД. Байт-код, сгенерированный Java-компилятором, «патчился» вставками, содержащими ссылки на ХП. Явным преимуществом было то, что изменения в программу могли вноситься без перекомпиляции, простым редактированием ассоциированного XML-файла. Минусом была необходимость синхронизации XML и Java кодов. Для этого разрабатывались дополнительные инструменты. Однако, мы могли бы использовать атрибуты на C# вместо того, чтобы беспокоиться о синхронизации.
C# представляет атрибуты, которые позволяют вам хранить информацию прямо в исходном коде. Атрибуты помещаются в квадратные скобки, например [MTAThread], строкой выше хозяина атрибута (например класса, поля, метода и т.п.). Атрибуты в C# могут быть использованы для пометки полей, методов, классов и т.п. таким образом, чтобы другая программа могла их интерпретировать. Например, можно послать компилятору инструкции по выдаче предупреждающего сообщения
[Obsolete("Этот делегат не стоит использовать. В следующих версиях он поддерживаться не будет.")]
или сгенерировать ошибку для устаревших методов.
[Obsolete("Этот метод устарел с версии 1.2.3.4", true)]
Подробнее смотрите помощь по [ObsoleteAttribute] в спецификации языка C#.
В C++ атрибуты указываются между квадратными скобками, в Visual Basic – между угловыми.

Примеры

Атрибут

Значение
[STAThreadAttribute]
public static int Main(string[] args) { }
Указывает, что модель приложения является однопоточной. Хозяином атрибута здесь является метод. Также известно, что есть класс STAThreadAttribute, с конструктором, не имеющим параметров STAThreadAttribute()
[MTAThread] [MTAThread] – сокращение для [MTAThreadAttribute], в C#. Другими словамисуффикс "Attribute" опционален. Если вы работаете в смешанной среде, то надо писать полное имя MTAThreadAttribute, а не сокращение MTAThread.
[Obsolete] [Obsolete] м.б. использован для пометки хозяина атрибута как устаревшего. Компилятор обработает этот атрибут и либо сгенерирует ошибку, либо предупреждение.
[AttributeUsageAttribute(AttributeTargets.Field)]
public class PrecisionAttribute
{
public void PrecisionAttribute(int length, int precision) {
} }
Указывается, что атрибут, определённый пользователем, PrecisionAttribute, может быть применен только к полям. Также показано, что есть конструктор с именем AttributeUsageAttribute(AttributeTargets t) в классе AttributeUsageAttribute. Этот класс AttributeUsageAttribute is также определён в среде .Net.
[In] или [InAttribute] Оба означают одно и тоже.
[InAttribute, Out, CustomMarshaller(true, UnmanagedType.U4))]
TraderIdentifier trId
или
[In] [Out] [CustomMarshaller(true, UnmanagedType.U4)]
TraderIdentifier trId;
Атрибуты могут объединяться с использованием точки с запятой или указываться отдельно с использованием квадратных скобок.
[DllImport("User32.dll")]
public static extern IntPtr GetWindow(IntPtr hWnd, int uCmd);
Инструктируем компилятор о вставке кода для динамического доступа к dll.

Пример кода

Ниже есть пример, показывающий как можно создать пользовательский атрибут и код с его использованием в одной программе. Он просто позволит вам хранить форматирование с объявлением. Например так:

[Formatting("###-##-####")]
public int socialSecurityNumber;

[FormattingAttribute("(###) ###-####")]
public long phoneNumber;

Иерархия классов

Вот иерархия классов для нашего примера*.
Класс AttributeSample выполняет основную функциональность. FormattingAttribute – это код для атрибута и содержит private-класс Core со своей фундаментальной функциональностью. Классы Person, USCitizen, USEmployee реализуют интерфейс ISupportsFormatting и иерархические отношения между ними показаны ниже. ISupportsFormatting нуждается в реализации методов string Fields() и string Field (string field) классом, реализующим этот интерфейс.

*Примечание переводчика: Собственно код приложения с реализацией этой идеи и схему классов вы можете найти по ссылке, указанной в начале статьи; здесь они не размещены, поскольку размер рассылки ограничен.


{К содержанию}

Форумы .Net на SQL.RU - вопросы оставшиеся без ответа

Получить дату создания загружаемого файла ASP.NET
не работает Ambientware AutoFire
Сообщение окну
ладно, ... а кто нибудь сереализовал TreeNode?


На этом двадцать второй выпуск .Net Собеседника закончен.
До следующего номера.



Чужа Виталий Ф. aka hDrummer,
hdrummer@sql.ru - жду ваши предложения, вопросы и замечания.


Рассылки Subscribe.Ru
.Net Собеседник - Новости мира Net, C#, ASP.Net

http://subscribe.ru/
http://subscribe.ru/feedback/
Подписан адрес:
Код этой рассылки: comp.soft.prog.dotnetgrains
Отписаться

В избранное