On this page you will find a sample piece of code that shows you exactly how code that uses this library might look.

There is also a listing of the API on the page API Reference and also a page with some helpful information on how to consume the interfaces.

Code Sample using the CSM

Here is a sample test class that does the three things you need:

  1. Create the instances of the IServiceConfigurator and IServiceLocator.
  2. Call the IServiceConfigurator (most likely quite a few times) to configure the underlying container.
  3. Call the IServiceLocator each time you wish to obtain an instance you want to use.

Just read along from top to bottom in the code below which is commented to explain what is going on. The faked ‘Application’ below is in the form of Visual Studio TestClass.

[TestClass]
public class Sample_code_that_uses_the_CSM
{
  // Simple 'domain' for us to play with; Foo, Bar, Baz and Qux

  public class Foo
  {
    public Foo(IBar bar, IBaz baz)
    {
      Bar = bar;
      Baz = baz;
    }

    public Foo(IBar bar, IBaz baz, IQux qux)
    {
      Bar = bar;
      Baz = baz;
      Qux = qux;
      throw new Exception("This constructor cannot be used.");
    }

    public IBar Bar { get; set; }
    public IBaz Baz { get; set; }
    public IQux Qux { get; set; }
  }

  public interface IBar
  { }

  public interface IBaz
  { }

  public interface IQux
  { }

  // Please notice that the implementations of the interfaces in our 'domain' may be (and probably are)
  // located on quite different places in the application.
  // For this sample they are all right here:

  public class Bar : IBar { }

  public class Baz : IBaz
  {
    public IBar Bar { get; set; }
  }

  public class Qux : IQux
  {
    public IBar Bar { get; set; }
  }

  //
  // Here begins our 'Application'
  //

  static IServiceLocator ServiceLocator;
  static IServiceConfigurator ServiceConfigurator;

  /// <summary>
  /// This is typically done on app startup.
  /// </summary>
  /// <remarks>This is the only piece of code that has to have a reference to the IoC container we are using; in this case Unity.</remarks>
  [ClassInitialize]
  public static void Create_ServiceLocator_and_ServiceConfigurator(TestContext testContext)
  {
    var container = new UnityContainer();
    ServiceLocator = new UnityServiceLocator(container);
    ServiceConfigurator = new UnityServiceConfigurator(ServiceLocator);
  }

  /// <summary>
  /// This is typically done close to the implementations of your code and is very likely not aware of the application.
  /// </summary>
  /// <remarks>You have to call to this code from your app bootstrapping and there are trade offs in so doing.
  /// There are ways to handle this with for instance extensibility functionality to dynamically find this code and execute it.</remarks>
  [TestInitialize]
  public void Configure_application_using_ServiceConfigurator()
  {
    // 
    // Please notice how the code below only uses IServiceConfigurator without any knowledge of the underlying container.
    // 

    ServiceConfigurator.Configure<Foo>()
                       .InjectionConstructor(() => new Foo((IBar)null, (IBaz)null), "a key for bar")
                       .InjectionProperties(f => f.Qux);

    ServiceConfigurator.RegisterType<IBar, Bar>("a key for bar")
                       .AsSingleton();

    ServiceConfigurator.RegisterType<IBar, Bar>();

    ServiceConfigurator.RegisterType<IBaz, Baz>()
                       .InjectionProperties(b => b.Bar);

    ServiceConfigurator.RegisterType<IQux, Qux>()
                       .InjectionProperties(new KeyedPropertyExpression<Qux>(q => q.Bar, "a key for bar"));
  }

  /// <summary>
  /// This is typically done anywhere in your app that you need an instance of something.
  /// </summary>
  /// <remarks>In any chain of dependency injections there must always be a root.
  /// In a desktop app perhaps a form, in an MVC app it's the controller and so on. In this sample it's the Foo class.</remarks>
  [TestMethod]
  public void Locate_services_inside_my_app()
  {
    //
    // Here we just use the IServiceLocator without knowing anything about the underlying container.
    //

    var foo = ServiceLocator.GetInstance<Foo>();

    // Foo got injected
    Assert.IsNotNull(foo.Bar);
    Assert.IsNotNull(foo.Baz);
    Assert.IsNotNull(foo.Qux);

    var qux = foo.Qux as Qux;
    // The Qux instance got injected
    Assert.IsNotNull(qux.Bar);
    // Foo and Qux are registered for the same singleton instance of Bar named "a key for bar"
    Assert.AreSame(foo.Bar, qux.Bar);

    var baz = foo.Baz as Baz;
    // The Baz instance got injected
    Assert.IsNotNull(baz.Bar);
    // Baz is not registered for that same instance as Foo and has an instance of it's own.
    Assert.AreNotSame(foo.Bar, baz.Bar);
  }
}

Last edited Sep 2, 2010 at 2:46 PM by noopman, version 4

Comments

No comments yet.