Automation and Extensibility issue

Today I wrote a wrapper to be in control when unit testing some code that uses System.Random. After completing the task, which is mindless automation, I decided to create a T4 template for it. After completing the few lines in a separate solution I copied it over only to find some ugly error being generated.

After some oldschool write-debug-to-output, I found the issue to be the dots in the namespace. Come on Microsoft, everybody uses dots in their namespace. The best practice is something like Company.Product.Library …

The solution is to avoid dots (joke) or to query one level deeper to find the namespace. Codesample below.

<#@ template debug="true" hostSpecific="true" #>
<#@ output extension=".cs" #>
<#@ Assembly Name="System.Core" #>
<#@ assembly name="EnvDTE" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="EnvDTE" #>
// ----------------------------
// Generated on <#= System.DateTime.Now.ToString() #> 
// any changes will be lost the next time this file is generated
// This file contains a list of all classes in the project
// ----------------------------

<#
var visualStudio = (Host as IServiceProvider).GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
var project = visualStudio.Solution.FindProjectItem(Host.TemplateFile).ContainingProject as EnvDTE.Project;
var rootNamespace = (string)project.Properties.Item("RootNamespace").Value;

// chop into parts between the dots
var dots = rootNamespace.Split('.');
var codenamespace = project.CodeModel.CodeElements.OfType<EnvDTE.CodeNamespace>().Where(cn => cn.FullName == dots[0]).First();
// query with an extra part of the namespace (Company, Company.Product, Company.Product.Library)
for(int i = 1; i < dots.Length; i++) {
	var filter = string.Join(".", dots.Take(i + 1));
	codenamespace = codenamespace.Members.OfType<EnvDTE.CodeNamespace>().Where(cn => cn.FullName == filter).First();
}

if (codenamespace != null) {
	var classes = codenamespace.Members.OfType<EnvDTE.CodeClass>();
	foreach(var classItem in classes) WriteLine("// {0}", classItem.FullName);
} else {
	WriteLine("// namespace not found");
}
#>

Check back for future updates on generating design patterns as I am building myself a library.

Further reading:

[edit September 9, 2013]
Codesample optimization with namespace split on dots and query every part: Company, Company.Product, Company.Product.Library
[/edit]

About erictummers

Working in a DevOps team is the best thing that happened to me. I like challenges and sharing the solutions with others. On my blog I’ll mostly post about my work, but expect an occasional home project, productivity tip and tooling review.
This entry was posted in Tooling and tagged , , , . Bookmark the permalink.

2 Responses to Automation and Extensibility issue

  1. kiquenet says:

    Any final solution with full source code samples using Unit Testing C# and EnvDTE ? for VS 2008, VS2010 and VS 2012 ?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.