Archive for the ‘Programming’ Category
January 8th, 2009
So I had written a SmtpClientWrapper for System.Net.SmtpClient because the aforementioned class implements no interface making it impossible to perform dependency injection using it (as anyone who has to unit test any sort of email functionality can attest to). Then I had the idea that during production we may want to mirror email messages sent to a debugging email address so I also made a MirrorSmtpClientDecorator. Herein lies the problem - System.Net.MailMessage does not implement ICloneable and the MirrorSmtpClientDecorator.Send(MailMessage) either needs a copy or its going adversely affect MailMessage with a side affect (by altering the MailMessage.To MailAddressCollection for a second message sent to the debugging email addresses). I explored numerous ways to copy MailMessage and eventually I resorted to some brute force extension methods (to ObjectModel.Collection<T>; ShallowCopy and Replace, suck I know) but during my research I discovered some older MemoryStream serialization I refactored and felt its worth sharing.
The problem with this approach is that the class you want to deep copy requires that it be marked with the SerializableAttribute. I've noticed that a portion of my time is spent writing hackarounds for classes in the .NET BCL and MailMessage is no exception - yup no ICloneable and no SerializableAttribute either.
public class Serializer
{
public static void Serialize(Stream target, object source)
{
var formatter = new BinaryFormatter();
formatter.Serialize(target, source);
}
public static T Deserialize<T>(Stream source) where T : class
{
var formatter = new BinaryFormatter();
var obj = (T)formatter.Deserialize(source);
return obj;
}
}
public class MemorySerializer<T> : IDisposable where T : class
{
#region Member Variables
private readonly MemoryStream _ms;
#endregion
#region Constructors
public MemorySerializer(MemoryStream ms)
{
_ms = ms;
}
public MemorySerializer()
{
_ms = new MemoryStream();
}
#endregion
#region Methods
public MemorySerializer<T> Serialize(T obj)
{
Serializer.Serialize(_ms, obj);
_ms.Position = 0;
return this;
}
public T Deserialize()
{
return Serializer.Deserialize<T>(_ms);
}
#endregion
#region Implementation of IDisposable
public void Dispose()
{
if (_ms == null)
return;
try
{
_ms.Close();
}
finally
{
_ms.Dispose();
}
}
#endregion
}
public static class ObjectUtility
{
/// <summary>
/// Creates a deep copy of an object for any object which
/// supports binary serialization.
/// </summary>
/// <typeparam name="T">Type to serialize/deserialize.</typeparam>
/// <param name="source">Object to deep copy.</param>
/// <returns>New instance of the object with all properties and
/// fields that support serialization copied.</returns>
/// <remarks>This method isn't as fast as a provided Clone method
/// but when ICloneable is not implemented on a BCL class its a
/// pretty close substitute.</remarks>
public static T DeepCopy<T>(this T source) where T : class
{
T ret;
using (var ms = new MemorySerializer<T>())
{
ret = ms.Serialize(source).Deserialize();
}
return ret;
}
}
November 18th, 2008
So I've been off scratching the WoW-itch for a few days. I came back and found these wonderful pearls of programming related quotes from Jeff Atwood which I'm sure have been read by most everyone but require reiteration:
On programming and typing:
Don't just type random gibberish as fast as you can on the screen, unless you're a Perl programmer.
So true! And I love Perl.
On NP-Complete:
NP-complete problems are like hardcore pornography. Nobody can define what makes a problem NP-complete, exactly, but you'll know it when you see it.
Nothing but win right there.
October 23rd, 2008
Today I implemented the ConfigurationSection stuff in .NET you can use to interject your custom configuration structures into config files like web.config and app.config. I wanted to test not only my implementation, but the classes that rely on the configuration but it wasn't exactly clear how I could get ConfigurationManager to load an arbitrary configuration.
The solution is quite simple and I figured it out after a bit of trial and error. What got me was that I had a custom configuration file in a child directory of my unit test project("WebServices") and I had set the configuration file's build action to "Copy Always". I had thought it would end up in "bin\Debug" but it correctly ended up in "bin\Debug\WebServices" so that's an important thing to keep in mind.
Outsmarting ConfigurationManager also requires that you have an accompanying file (empty text file works) that the configuration applies to. So here's what the start of my [now working] test looks like:
private static RequestHandlerSection _section;
[TestFixtureSetUp]
public void Setup()
{
using (var sw =
File.CreateText(".\\WebServices\\RequestHandlerTests")
)
{
sw.Close();
}
var config = ConfigurationManager.OpenExeConfiguration(
".\\WebServices\\RequestHandlerTests"
);
_section = (RequestHandlerSection)
config.Sections[RequestHandlerSection.Name];
}
[Test]
public void WorkDamnYouTest()
{
Assert.IsNotNull(_section);
Assert.IsNotEmpty(_section.Security);
}
}
Ideally at some point in the future ConfigurationManager could get a Load(string xml) or some such so we don't have to deal with this nonsense. While I could add one with an extension method I'd like to see it get into the framework to improve unit testability.
October 21st, 2008
Three things have been bugging me lately about C#. Well one since I started using C# coming from writing a ton of unmaintainable Perl code. What C# needs:
- unless
- implies
- templates
unless
Unless is just a reversed if statement. Its actually quite simple and in some situations it improves code readability. This is personal opinion more so than anything else, but I feel strongly about it. Compare:
if (!property.CanRead)
continue;
to:
continue unless propery.CanRead;
So what it does is remove the negation from the if test (I mean, it is unless after all, isn't it?). It just flows better. "Oh, continue unless this condition is met."
implies
Extracting interfaces from existing classes is certainly easier with ReSharper, but I want more. I don't want to have to maintain separate interface files when the interfaces will match the implementation all of the time. I understand when you make interfaces and then code the implementation to them however that approach isn't always needed. I'll give a specific example: unit testing. I've started using StructureMap and Moq to significantly improve the quality of our tests, but in order to do that I had to StructureMap pluginify all of the IBATIS mappers we have written. In 100% of the cases the implementation of the mappers are the interfaces of the mappers, and now that I've gone and done this anytime a change needs to be made to a concrete mapper the interface will need to be updated as well - the dependency has been essentially reversed. I think this scenario will become more common as more people work to improve their unit tests, so I'd like to see something where:
public class PersonMapper : IPersonMapper
{
public Person Select(int id) { return null; }
public IList<Person> SelectAll() { return null; }
public void Create(Person p) { }
public void Update(Person p) { }
public void Delete(Person p) { }
}
public interface IPersonMapper
{
Person Select(int id);
IList<Person> SelectAll();
void Create(Person p);
void Update(Person p);
void Delete(Person p);
}
becomes:
public class PersonMapper implies IPersonMapper
{
public Person Select(int id) { return null; }
public IList<Person> SelectAll() { return null; }
public void Create(Person p) { }
public void Update(Person p) { }
public void Delete(Person p) { }
}
So this isn't a solution for contract by design, its just the opposite, a tightly bound interface to a concrete class. But what it does do is reduce lines of code and increases maintainability and decreases the pain of writing good unit tests to a degree. And yes, a tool could be used to do this (I've wrote one in fact), but I'm talking maintainability and ease of use here!
templates
C# generics are very nice, but they are not templates. Many people who can better articulate the problem than I have argued for them so I'll just post my recent headache as my argument of why I want templates:
private static volatile INodeMapper nodeMapper;
public static INodeMapper Node()
{
if (nodeMapper == null)
{
lock (typeof(INodeMapper))
{
if (nodeMapper == null)
nodeMapper = ObjectFactory.GetInstance<INodeMapper>();
}
}
return nodeMapper;
}
Because nodeMapper is declared volatile you cannot pass it using ref (or even out which would be less ideal than ref).
So imagine that code having to be written for every entity in your database. Again, a tool can do it, but that's not the correct answer to the problem. A preprocessor template here would be the only way to do what I want to accomplish in a sane manner. Until then I've used partial classes to break our mappers down to more maintainable levels (about 2000 lines of repetitious code into several smaller files alphabetically organized).
September 19th, 2008
The greatest problem I have encountered with the .NET framework (through 3.5) is that Dictionary instances are not serializable. You have to write custom serialization routines and its different if you are doing binary or XML serialization.
An important aspect to XML serialization to me is readability. If I'm serializing something to XML then I expect it to be readable and I prefer less nodey to more. I like to use attributes whenever possible.
I originally used some somewhat dated code I found on Matt Berther's blog and while it worked, it gave me the nodey version I didn't care much for:
<dictionary>
<item>
<key>type</key>
<value>resource</value>
</item>
<item>
<key>version</key>
<value>1</value>
</item>
</dictionary>
The value of the nodey version is that when the types represented by TKey and TValue are themselves serializable in a way that can allow them to be represented by their own XML object graphs. Ideally I wanted a format that could have output like:
<item key="type" value="resource" />
but still fall back to the more advanced nodey version as necessary, and mix and match (TKey could be a string while TValue could be a more complex serializable type, such as a domain class with many properties).
My solution was to establish what classes could be attributable:
public class Dictionary<TKey,TValue> : IDictionary<TKey, TValue>,
ISerializable,
IDictionary,
IXmlSerializable
...
private readonly static List<Type> _attributableTypes;
static Dictionary()
{
_attributableTypes = new List<Type>
{
typeof(Boolean),
typeof(Byte),
typeof(Char),
typeof(DateTime),
typeof(Decimal),
typeof(Double),
typeof(Enum),
typeof(Guid),
typeof(Int16),
typeof(Int32),
typeof(Int64),
typeof(SByte),
typeof(Single),
typeof(String),
typeof(TimeSpan),
typeof(UInt16),
typeof(UInt32),
typeof(UInt64)
};
}
private static bool IsAttributable(Type t)
{
return _attributableTypes.Contains(t);
}
And the meat of the code, the IXmlSerializable interface implementation:
System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema()
{
return null;
}
void IXmlSerializable.ReadXml(System.Xml.XmlReader reader)
{
// some types can be stored easily as attributes while others
// require their own XML rendering
Func<TKey> readKey;
Func<TValue> readValue;
var isAttributable = new { Key = IsAttributable(typeof(TKey)),
Value = IsAttributable(typeof(TValue)) };
// keys
if (isAttributable.Key)
{
readKey = () => (TKey)Convert.ChangeType(
reader.GetAttribute("key"), typeof(TKey)
);
}
else
{
var keySerializer = new XmlSerializer(typeof(TKey));
readKey = () =>
{
while (reader.Name != "key")
reader.Read();
reader.ReadStartElement("key");
var key = (TKey)keySerializer.Deserialize(reader);
reader.ReadEndElement();
return key;
};
}
// values
if (isAttributable.Value && isAttributable.Key)
{
readValue = () => (TValue)Convert.ChangeType(
reader.GetAttribute("value"), typeof(TValue)
);
}
else
{
var valueSerializer = new XmlSerializer(typeof(TValue));
readValue = () =>
{
while (reader.Name != "value")
reader.Read();
reader.ReadStartElement("value");
var value = (TValue)valueSerializer.Deserialize(reader);
reader.ReadEndElement();
return value;
};
}
var wasEmpty = reader.IsEmptyElement;
reader.Read();
if (wasEmpty)
return;
while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
{
while (reader.NodeType == System.Xml.XmlNodeType.Whitespace)
reader.Read();
var key = readKey();
var value = readValue();
Add(key, value);
if (!isAttributable.Key || !isAttributable.Value)
reader.ReadEndElement();
else
reader.Read();
while (reader.NodeType == System.Xml.XmlNodeType.Whitespace)
reader.Read();
}
reader.ReadEndElement();
}
void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)
{
Action<TKey> writeKey;
Action<TValue> writeValue;
var isAttributable = new
{
Key = IsAttributable(typeof(TKey)),
Value = IsAttributable(typeof(TValue))
};
if (isAttributable.Key)
{
writeKey = v => writer.WriteAttributeString("key",
v.ToString()
);
}
else
{
var keySerializer = new XmlSerializer(typeof(TKey));
writeKey = v =>
{
writer.WriteStartElement("key");
keySerializer.Serialize(writer, v);
writer.WriteEndElement();
};
}
// when keys aren't attributable, neither are values
if (isAttributable.Value && isAttributable.Key)
{
writeValue = v => writer.WriteAttributeString("value",
v.ToString()
);
}
else
{
var valueSerializer = new XmlSerializer(typeof(TValue));
writeValue = v =>
{
writer.WriteStartElement("value");
valueSerializer.Serialize(writer, v);
writer.WriteEndElement();
};
}
foreach (var key in Keys)
{
writer.WriteStartElement("item");
writeKey(key);
writeValue(this[key]);
writer.WriteEndElement();
}
}
Bonus: I also learned that multiline lambdas exist and I snuck in an anonymous type to boot. I like that I was able to take two separate approaches to XML serialization, distill their interfaces from their inner workings, and then just expose the correct method signature within a method to keep the iterative loop clean of if/else logic (even if I just moved the logic above the loop). To me this code seems much more readable than if I had kept everything in the loop.
Update: it helps to post working code. Also, here's a zip file with the implementation and some brief NUnit flavored tests.