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:

private FirstService service;
[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.

I left you the code of the util method…

public static void InjectObjects(Object instance)
{
   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:


Comments:
Interesting concept, however, it could be a little bit complex to achieve...
As far as I know, IBM Jazz Project aims to solve this kind of collaboration concerns inside the IDE. An IBM Guy will send me some information about Jazz because I couldn't find so much over the web. I only saw few screenshot...
 
Post a Comment



<< Home

This page is powered by Blogger. Isn't yours?