Many many developers have had the pleasure of playing around with a tool called CodeSmith. I certainly love what it does and have been using it since my university days. But when I went to the tool's website yesterday, I was deeply saddened to see that as from version 3.0, CodeSmith is not freeware anymore. If you look up 'sellout' in the dictionary, you might find a description that resembles the sequence of events here described.
Now the freeware version of CodeSmith is quite useful for simple tasks, but when advanced tasks are attempted, one has to resort to hacks. Let me illustrate with the all time classic example - overriding the default editor for a property. Presently, you would have to do something like the following in the script section of your template:
[Editor(typeof(MyEditor), typeof(UITypeEditor))]
public MyType MyProperty
{
get
{
return pMyProperty;
}
set
{
pMyProperty = value;
}
}
Wouldn't it be much easier to have something like what follows in the prologue if the template?
<%@ Property Name="MyProperty" Type="MyType" Editor="MyEditor" %>
Another problem that I'm having is activating a drop-down editor in a property. Presently, I have to make an assembly that has a TypeConverter that will provide CodeSmith's PropertyGrid with values. The following code illustrates what I currently have to do:
public class MyConverter : StringConverter
{
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return false;
}
public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(
ITypeDescriptorContext context)
{
return new StandardValuesCollection(new string[] {"String 1", "String 2"});
}
}
And in the script section of the template:
[TypeConverter(typeof(MyConverter))]
public string MyProperty
{
get
{
return pMyProperty;
}
set
{
pMyProperty = value;
}
}
Contrast that with something like this:
<%@ Property Name="MyProperty" Type="System.String" DropDownValues="GetMyPropertyValues" %>
...and in the script section of the template:
private void GetMyPropertyValues(object sender, DropDownValuesEventArgs e)
{
e.Values = new StandardValuesCollection(new string[] {"String 1", "String 2"});
}
Much easier - and you now don't need an extra assembly.
Finally, a pet peeve, is the way Xml Serialization is handled in CodeSmith. I think that this might be an issue with the way CodeSmith interacts with the .NET Serializer, but I still don't know what to do. Here is a snippet of code in my template:
public VeloTestFieldCollection ReceiveFields
{
get
{
return pReceiveFields;
}
set
{
pReceiveFields = value;
}
}
When I try and save the properties to xml, it appears as "(collection)" and all the information in the collection is lost. What to do? Help!?!?! And as an aside, I don't like the fact that CodeSmith generates a set accessor for collections. Bad CodeSmith.
If you use CodeSmith, I'm sure that you've gained much benefit from it. But if you've also experienced frustration in creating templates, why not share it with the rest of us and comment about it.