четверг, 8 июля 2010 г.
пятница, 30 апреля 2010 г.
суббота, 24 октября 2009 г.
Amazon AWS Service WCF Mutual Certificate authentication - fail
Придется пользоваться старым вариантом, на WSE 3.0
воскресенье, 14 июня 2009 г.
Кодогенерация T4
Нет, это не про Терминатора :)
Это про использование T4 Text Template Transformation Toolkit, встроенного в Visual Studio 2008 для автоматической генерации кода.
Кратко задача – есть исходники. Опять-то таки сгенерированные, но другим инструментом, Thrift.
Код на C#, публичные поля и свойства в классах с одинаковым именем, только различаются регистром.
Код необходимо использовать из VB.NET. Упс! VB.NET нечувствителен к регистру! Приплыли.
Исходники конечно есть, но они регулярно обновляются – так что их исправлять нельзя.
Классы не помечены partial – расширить напрямую тоже нельзя.
Но у нас же есть extension методы – спасибо .NET 3.5! Можно понаписать методов (эх… пока только методы, эктеншен свойств нет) с названием совпадающим со свойствами, но с каким-нибудь префиксом, подчеркиванием например.
Ок, хорошо. Но вручную писать обертки на 20 классов?! Да они еще, как я сказал, могут обновиться в будущем. Тут нужна автоматизация… И в VS 2008 она уже встроена – движок кодогенерации T4.
Файлы с расширением tt. Синтаксис очень похож на ASP.NET, только исполняются внутри Visual Studio (и не только, хостом может выступать любое приложение, и ваше в том числе).
И вот всё волшебство:
<#@ template language="C#v3.5" hostspecific="true" #>
<#@ assembly name="EDAM.dll" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.CodeDom" #>
<#@ import namespace="System.CodeDom.Compiler" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="Evernote.EDAM.Type" #>
// Autogenerated by <#= Host.GetType() #>
// <#= DateTime.Now #>
// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
namespace Evernote.EDAM.Type
{
<# foreach (var @class in Assembly.GetAssembly(BaseClass)
.GetExportedTypes()
.Where(type => !type.IsNested)
.Where(type => type.Namespace == BaseClass.Namespace)) { #>
public static class <#= @class.Name #>Ex
{
<# foreach (var prop in @class.GetProperties()) { #>
public static <#= PrintType(prop.PropertyType) #> _<#= prop.Name #>(this <#= prop.DeclaringType #> value)
{
return value.<#= prop.Name #>;
}
<# }#>
}
<# } #>
}
<#+ Type BaseClass = typeof(Note); #>
<#+
public string PrintType(Type type)
{
var typeExpr = new CodeTypeReferenceExpression(type);
var csProvider = Microsoft.CSharp.CSharpCodeProvider.CreateProvider("C#");
var writer = new StringWriter();
csProvider.GenerateCodeFromExpression(typeExpr, writer, new CodeGeneratorOptions());
return writer.ToString();
} #>
Вкратце, по шагам:
C# note.Attributes.Lattitude
VB.NET note._Attributes._Lattitude
Полезные ссылки:
Это про использование T4 Text Template Transformation Toolkit, встроенного в Visual Studio 2008 для автоматической генерации кода.
Кратко задача – есть исходники. Опять-то таки сгенерированные, но другим инструментом, Thrift.
Код на C#, публичные поля и свойства в классах с одинаковым именем, только различаются регистром.
Код необходимо использовать из VB.NET. Упс! VB.NET нечувствителен к регистру! Приплыли.
Исходники конечно есть, но они регулярно обновляются – так что их исправлять нельзя.
Классы не помечены partial – расширить напрямую тоже нельзя.
Но у нас же есть extension методы – спасибо .NET 3.5! Можно понаписать методов (эх… пока только методы, эктеншен свойств нет) с названием совпадающим со свойствами, но с каким-нибудь префиксом, подчеркиванием например.
Ок, хорошо. Но вручную писать обертки на 20 классов?! Да они еще, как я сказал, могут обновиться в будущем. Тут нужна автоматизация… И в VS 2008 она уже встроена – движок кодогенерации T4.
Файлы с расширением tt. Синтаксис очень похож на ASP.NET, только исполняются внутри Visual Studio (и не только, хостом может выступать любое приложение, и ваше в том числе).
И вот всё волшебство:
<#@ template language="C#v3.5" hostspecific="true" #>
<#@ assembly name="EDAM.dll" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.CodeDom" #>
<#@ import namespace="System.CodeDom.Compiler" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="Evernote.EDAM.Type" #>
// Autogenerated by <#= Host.GetType() #>
// <#= DateTime.Now #>
// DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
namespace Evernote.EDAM.Type
{
<# foreach (var @class in Assembly.GetAssembly(BaseClass)
.GetExportedTypes()
.Where(type => !type.IsNested)
.Where(type => type.Namespace == BaseClass.Namespace)) { #>
public static class <#= @class.Name #>Ex
{
<# foreach (var prop in @class.GetProperties()) { #>
public static <#= PrintType(prop.PropertyType) #> _<#= prop.Name #>(this <#= prop.DeclaringType #> value)
{
return value.<#= prop.Name #>;
}
<# }#>
}
<# } #>
}
<#+ Type BaseClass = typeof(Note); #>
<#+
public string PrintType(Type type)
{
var typeExpr = new CodeTypeReferenceExpression(type);
var csProvider = Microsoft.CSharp.CSharpCodeProvider.CreateProvider("C#");
var writer = new StringWriter();
csProvider.GenerateCodeFromExpression(typeExpr, writer, new CodeGeneratorOptions());
return writer.ToString();
} #>
Вкратце, по шагам:
- Перебираем все классы из сборки, из нужного пространства имен.
- Для каждого класса генерируем статический класс с таким-же именем и суффиксом Ex.
- Перебираем все свойства класса.
- Генерируем экстеншен-метод нужного типа с именем как оригинальное ствойство, но с префиксом _.
- Для генерация имени нужного типа используется маленькая хитрость. Так как по простому дженерики будут выводиться в IL-нотации, т.е. например System.Generic.List’1[System.String]. И это не будет компилироваться. Надо System.Generic.List<System.String> (для C#). Что и делается через CodeDom. Так как сборка на C# – то и провайдер для C# используется. Можно генерировать и в VB. Как в CodeDom, так и в самом T4 кстати.
C# note.Attributes.Lattitude
VB.NET note._Attributes._Lattitude
Полезные ссылки:
- T4: Text Template Transformation Toolkit
- Generating Artifacts By Using Text Templates (раздел в MSDN)
- Visual T4 (плагин для редактирования файлов tt с подсветкой)
Ярлыки:
.NET,
.NET 3.5,
Кодогенерация,
Code Generation,
CodeDom,
Development,
evernote,
T4,
VB.NET
пятница, 15 мая 2009 г.
Яндекс.Фотки API
Яндекс.Фотки наконец-то открыли официальный API. Базирован на AtomPub.
Решил перевести существующие решения для Яндекс.Фоток на него (Picasa, Архив, WLW, WLPG).
Для работы с AtomPub в .NET попробовал несколько вариантов:
После экспериментов остановился на последнем. Очень мне нравится конвергенция в современном мире - я объединяю двух непримиримых конкурентов.
Решил перевести существующие решения для Яндекс.Фоток на него (Picasa, Архив, WLW, WLPG).
Для работы с AtomPub в .NET попробовал несколько вариантов:
- System.ServiceModel.Syndication из .NET 3.5
Базовые сущности ServiceDocument, AtomFeed, AtomEntry.
Но все изменяющие операции (Insert, Update, Delete) приходится делать врукопашную, через WebRequest. - Microsoft.Web.AtomPub
Небольшая надстройка над первым пунктом из Live Framework SDK. Негибкая, на некоторых операциях с сервером от Яндекса давится. - AtomSite
Как оказалось, это серверная имплементация AtomPub, не клиент. - GData .NET Client Library
Предназначается для работы с сервисами Гугла, но есть базовая библиотека для работы с AtomPub, непривязанная к особенностям Гугла. Немного перегружена, но довольна гибкая и в исходниках!
После экспериментов остановился на последнем. Очень мне нравится конвергенция в современном мире - я объединяю двух непримиримых конкурентов.
namespace Team23.YandexFotki{public class YaDataRequest : GDataRequest
{...
}
}
Ярлыки:
.NET,
.NET 3.5,
Яндекс.Фотки,
API,
AtomPub,
Development,
Team 23
воскресенье, 3 мая 2009 г.
Визуальный поиск по книгам с учетом русской морфологии.
Вся информация: название, обложка, издательство, год выпуска, цены - не отрываясь от поля поиска.
Подписаться на:
Сообщения (Atom)