Wednesday, March 24, 2010

Implementing an IoC container in Silverlight on Windows phone 7 series

I wrote a while ago about implementing a Service Locator for the CompactContainer on the Compact Framework here: http://www.simonrhart.com/2010/02/implementing-commonservicelocator-on.html

I mentioned in that post that I was using the CompactContainer for the CF freely available here: http://code.google.com/p/compactcontainer/ But now as I'm getting into Silverlight as it's the technology of choice when building applications for the Windows phone 7 series platform (as well as XNA), I needed an IoC container to solve the same problems on Silverlight as they do on the Compact Framework.

So I tried to port the container along with the ServiceLocator as blogged about before. I recieved errors in the ComponentCollection class after I tried to compile under Silverlight. Mainly because the following predicate methods such as:
  1. List.FindAll
  2. List.Find

Are not supported in Silverlight 3 as the documentation suggests. However, they are in XNA. As the generic List class belongs to mscorlib.dll (System.Collections.Generic) I noticed that mscorlib is shared for both XNA and Silverlight applications on WP7. I'm trying to find out why this is, or if there is a way of making those methods work in Silverlight.

Anyway it's not the end of the world that those methods are not in Silverlight, all I had to do was replace the following methods in the ComponentCollection class:


public List<ComponentInfo> GetComponentInfoListFor(Type serviceType)
{
return _list.FindAll(ci => ci.ServiceType == serviceType);
}

public ComponentInfo FindForService(Type serviceType)
{
return _list.Find(ci => ci.ServiceType.Equals(serviceType));
}

public ComponentInfo FindForClass(Type classType)
{
return _list.Find(ci => ci.ClassType.Equals(classType));
}

public ComponentInfo FindKey(string key)
{
return _list.Find(ci => ci.Key.Equals(key));
}
With the following code:
public List GetComponentInfoListFor(Type serviceType)
{
List<ComponentInfo> results = new List<ComponentInfo>();

foreach(ComponentInfo component in _list)
{
if (component.ServiceType == serviceType)
results.Add(component);
}
return results;
}

public ComponentInfo FindForService(Type serviceType)
{
ComponentInfo result = null;
foreach(ComponentInfo component in _list)
{
if (component.ServiceType == serviceType)
{
result = component;
break;
}
}
return result;
}

public ComponentInfo FindForClass(Type classType)
{
ComponentInfo result = null;
foreach (ComponentInfo component in _list)
{
if (component.ClassType.Equals(classType))
{
result = component;
break;
}
}
return result;
}

public ComponentInfo FindKey(string key)
{
ComponentInfo result = null;
foreach (ComponentInfo component in _list)
{
if (component.Key.Equals(key))
{
result = component;
break;
}
}
return result;
}
That was all I had to change everything else just compiled and worked. Full dependency injection worked as per on the Compact Framework. It seems moving to Silverlight is going to be less painful than I originally thought!

No comments: