На момент написания статьи была доступна версия 1.35, релиз которой доступен здесь. Не буду вдаваться в подробности моей задачи, а просто приведу простой Hello-world пример работы с FxCop библиотекой. Итак после установки FxCop, добавим в наш проект новый T4 файл (TestTemplate.tt) содержащий следующий код:
<#@ template debug="true" hostSpecific="true" #>
<#@ output extension=".T4.txt" #>
<#@ assembly name="C:\Program Files\Microsoft FxCop 1.35\FxCopSdk.dll" #>
<#@ assembly name="C:\Program Files\Microsoft FxCop 1.35\Microsoft.Cci.dll" #>
<#@ import namespace="Microsoft.Cci" #>
<#
string assemblyPath = @"...путь к нашей сборке...";
// Загрузка сборки без блокировки (аналог Assembly)
AssemblyNode assembly = AssemblyNode.GetAssembly(assemblyPath);
// Указываем какое пространство имен
Identifier namespaceId = Identifier.For("SomeNamespace");
// Указываем какой тип (у нас это имя класса)
Identifier typeId = Identifier.For("SomeType");
// Получаем полную информацию о типе (аналог System.Type)
TypeNode type = assembly.GetType(namespaceId, typeId);
// Перечислим все члены типа (свойства, методы, события)
foreach(Member member in type.Members)
{
// Публичный ли член
if(member.IsPublic)
{
WriteMember(member);
}
}
#>
<#+
void WriteMember(Member member)
{
// Если член является свойством
if(member is Property)
WriteProperty(member as Property);
}
void WriteProperty(Property property)
{
// Получим имя свойства (полное имя, имя)
Identifier name = property.Name;
// Получим CLR тип свойства System.Type.
System.Type type = property.Type.GetRuntimeType();
// Форматируемый вывод.
WriteLine("Property '{0}' type of '{1}'", name, type);
}
#>
Выполнив "Run Custom Tool" на шаблоне T4 мы получим текстовый файл (TestTemplate.T4.txt), в котором перечилены все публичные свойства указанного типа, с указанием имени свойства и его CLR типа:
Property 'SomeProperty' type of 'System.Int32'
Так как сейчас я не генерировал код, я просто вывел результат в обычный текстовый файл.
Оригинальный тип:
namespace SomeNamespace
{
public class SomeType
{
public int SomeProperty
{
set; get;
}
public void SomeMethod()
{
}
}
}
Дальше можно усложнить нашу разметку. Например, разметка в виде C# кода, для получения исходника, или разметка в виде XML, CSV и другие.
Ссылки:
В конце шаблона рекомендую ещё вызвать assembly.Dispose(), иначе, как показывает практика, иногда блокируются pdb файлы, что мешает сборке.
ОтветитьУдалить@MeF
ОтветитьУдалитьПока блокировок не замечал, но спасибо за совет, явный вызов Dispose никогда не будет лишним.
Тоже сейчас пишу кодогенератор в VS2010 и у меня сборка блокируется после каждого выполнения T4. MeF, Спасибо за совет.
ОтветитьУдалитьЯ бы для решения подобной задачи воспользовался бы Mono::Cecil, вместо FxCop
ОтветитьУдалить@Stanislavus
ОтветитьУдалитьСпасибо, надо будет глянуть что это такое. Пока я слышал что это AOP framework.