Resolving Sitecore configuration entries using IoC with Named Components

A while back I covered off How to resolve Sitecore commands & pipelines from IoC. This I have used to great effect, to the point I can’t remember the last time I wrote a pipeline entry with a parameter-less constructor. This in itself has aided Unit Testing of pipelines so much I would consider it a must for all Sitecore development.

Recently however, I was faced with an instance where I now had to resolve two near identical items from my IoC container. In a regular .net application, I would simply use the named component functionality of the container and resolve at least one of my instances using such a name. In the case of Sitecore though – I didn’t have any more parameters to play with, and I mistakenly thought I only had the type name.

On closer investigation (and re-reading my own blog post) I noticed that it is simply an identifier NOT a fully qualified reference, meaning I could stuff in whatever I liked – down goes the shed door and cue the music…..

Below is a modified version of the same basic prisn is what I came up with for the original post, this time – you can now add a | (pipe) character and follow it with the name of the component from your IoC container. I have used Castle Windsor for this example, but the principle would work for pretty much any main stream IoC container (I may even write a version for Agnostic IoC ;).

using System;
using Castle.Windsor;
using Sitecore.Reflection;

namespace MyNamespace
{
    public class WindsorFactory : IFactory
    {
        private static readonly IWindsorContainer container = new WindsorContainer();

        public static IWindsorContainer Container
        {
            get { return container; }
        }
        public object GetObject(string identifier)
        {
            if (identifier.IndexOf("|", StringComparison.InvariantCultureIgnoreCase) >= 0)
            {
                return GetNamed(identifier);
            }

            return GetDefault(identifier);
        }

        private static object GetDefault(string identifier)
        {
            Type type = Type.GetType(identifier);
            return Container.Resolve(type);
        }

        private static object GetNamed(string identifier)
        {
            var elems = identifier.Split('|');
            string typeName = elems[0];
            string name = elems[1];
            Type type = Type.GetType(typeName);
            return Container.Resolve(name, type);
        }
    }
}

Your pipeline entry then looks something like this, where ‘demo’ is the name of the component you have registered.

<processor mode="on" ref="MyNamespace.PrismDataProvider, MyNamespace|demo" factory="WindsorFactory"/>

Hope this helps

Additional Reading

Advertisements

6 thoughts on “Resolving Sitecore configuration entries using IoC with Named Components

  1. Hi

    Thanks for sharing this, it’s great πŸ™‚ I used your implementation for events & pipelines during the Hackathon last weekend. Unfortunately this doesn’t seem to work for commands, as the CommandManager from Sitecore doesn’t allow the resolving classes over a factory. Did you find a solution for this? Or how do you resolve classes within a Sitecore command?

    Greets,
    Kevin

    • Thanks for the response Kevin – always good to know someone is reading πŸ˜€

      Hmmm – I thought I had done one on commands in our current solution – will double check. I know the factory is not available for all configuration types.

      Where it is not available, I tend to use a poor mans service locator implementation, something along the lines of (assuming the locator is called LocatorContainerManager)

      public MyClass() : this(LocatorContainerManager.Resolve(), LocatorContainerManager.Resolve())
      {
      }

      public MyClass(IDependency1 dependency1, IDependency2 dependency2)
      {
      // do something with dependencies here
      }

      This, whilst not a great solution, is one I can live with in terms of the following statements

      – NO logic is ever added to the parameterless constructor
      – The LocatorContainerManager is fully unit tested

      This reduces the risk as much as we can realistically

  2. hehe, I knew why you wrote this directly after my comment πŸ˜‰ It was lazyness (because I know Ninject best), I would also use another container for the next upcoming projects πŸ™‚

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s