Thursday, August 03, 2006
Injecting Spring.Net Objects in NUnit Tests
If you are using Spring.Net and NUnit, you probably have noticed that does not exist a declarative way to inject Objects (or Services). So it seems easy I search a little in google and how I did not found results in a nutshell I decided to develop a first little version of the solution I need.
First of all, I thought in an Attribute to define which Spring’s Object should be injected in a property or field… so:
///
/// The Attribute lets inject a Spring Object in properties or fields
///
[Serializable, AttributeUsage(AttributeTargets.Field | AttributeTargets.Property,
Inherited = true)]
public sealed class InjectSpringAttribute : Attribute
{
private string objectName;
public InjectSpringAttribute(string objectName)
{
this.objectName = objectName;
}
///
/// Returns the Object name that must be injected in the property or field
///
public string ObjectName{get{ return this.objectName;}}
}
Now, you could use the attribute as follows:
[InjectSpring("FirstService")]
public FirstService Service
{
get { return service; }
set { service = value; }
}
[InjectSpring("FirstService")]
private FirstService serviceField;
And you are not suppose to obtain IApplicationContext, getObject(…), bla bla.. anymore. The only issue remains is to define the way the attribute will be processed. For now, I have not a really elegant way to do this (in java I had been used AspectJ but with .Net???)… so I have a base TestCase from which all others Testcases extend and in the SetUp method I execute the following util static method: InjectObjects(instance) whose responsibility is to find all properties and fields decorated with the InjectSpringAttribute and set them the requested object.
{
Object springObject;
BindingFlags binding = BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic;
foreach (PropertyInfo propertyInfo in instance.GetType().GetProperties( binding ) )
{
if(TryGetSpringObject(propertyInfo.GetCustomAttributes(
typeof(InjectSpringAttribute), true),out springObject))
{
propertyInfo.SetValue(instance, springObject, null);
}
}
foreach (FieldInfo fieldInfo in instance.GetType().GetFields(binding))
{
if(TryGetSpringObject(fieldInfo.GetCustomAttributes(
typeof(InjectSpringAttribute), true),out springObject))
{
fieldInfo.SetValue(instance, springObject);
}
}
}
private static bool TryGetSpringObject(Object[] customAttrs,out Object springObject )
{
if (customAttrs != null && customAttrs.Length > 0)
{
foreach( object customAttr in customAttrs)
{
InjectSpringAttribute attr = customAttr as InjectSpringAttribute;
if (attr != null)
{
springObject = ContextRegistry.GetContext().GetObject(attr.ObjectName);
return true;
}
}
}
springObject = null;
return false;
}
Labels: .Net