Mike Taulty's Blog
Bits and Bytes from Microsoft UK
Rough Notes on Unity

Blogs

Mike Taulty's Blog

Elsewhere

Archives

I’ve been looking at Unity a little lately.

I appreciate that this doesn’t necessarily fall into the category of “new” as it’s been around for a while but I’m meeting more and more developers who are using it ( or other comparable frameworks ) and it also crops up in frameworks like Prism which, again, I’m seeing more and more people either using or referencing as they do work with WPF and/or Silverlight.

What’s Unity?

It’s a “dependency injection container”.

Now, at that point a bunch of folks reading this will say “Yes, we know and we’re already using it for reasons A, B, C or we’ve elected not to use it for reasons X,Y,Z ” and I imagine a bunch of other folks might say;

“Huh? What’s a dependency injection container?”

This post is for the latter people – it’s not meant to be exhaustive but hopefully it’s not completely unhelpful either :-)

The key word here is dependency. In software, we all know what it means to take dependencies on other components. Examples;

  1. The other component ships late and breaks your schedule
  2. The other component has a bunch of defects that make your component/app look bad
  3. The other component brings in a bunch of dependencies you never wanted to take
  4. The other component uses too many resources making your component/app look bad again
  5. The other component gets rev’d at the last minute, breaking your component
  6. It’s difficult to test your component in isolation from the other component because it makes lots of calls into it
  7. It’s difficult to replace the other component because your component has become so intertwined with it

I don’t think that Unity ( or similar frameworks – I’ll stop writing that part now I’ve made it clear that there are others ) really helps too much with points 1-5 but it does help with points 6-7. Actually, it might even help with some of the others as well.

If we imagine a contrived example. I might have a simple calculation component that looks like this;

class Calculator
{
  public Calculator()
  {

  }
  public double Add(double x, double y) 
  { 
    return (x + y); 
  }
  public double Subtract(double x, double y) 
  { 
    return (x - y); 
  }
  public double Multiply(double x, double y) 
  { 
    return (x * y); 
  }
  public double Divide(double x, double y) 
  { 
    return (x / y); // Woops, Div/0.
  }
  public double Root(double x)
  {
    return (Math.Sqrt(x));
  }
}

Ok, so it’s code no-one’s ever going to write and it makes sense more as static methods but I’ll ignore that here. Now, with this fantastic new Calculator capability I can write a class that ( e.g. ) calculates some higher-level statistical functions such as;

class Statistics
{
  public Statistics()
  {
    calculator = new Calculator();
  }
  public double StandardDeviation(params double[] values)
  {
    double average = 0;

    foreach (var item in values)
    {
      average = calculator.Add(average, item);
    }
    average = calculator.Divide(average, values.Length);

    double stdev = 0;

    foreach (var item in values)
    {
      double value = calculator.Subtract(average, item);
      value = calculator.Multiply(value, value);
      stdev = calculator.Add(stdev, value);
    }
    stdev = calculator.Divide(stdev, values.Length);

    return (calculator.Root(stdev));
  }
  Calculator calculator;
}

Again, not code that the world’s been crying out for but you get the idea. Now, I’ve built myself a nice simple dependency where the Statistics class relies on the Calculator class.

Not only does the Statistics class call methods on the Calculator class but it also goes ahead and makes an instance of the Calculator class as well – deciding to do that, in this case, as a one-off instantiation in its own constructor.

So, the Statistics class has explicit knowledge of the type Calculator – i.e. it knows that the calculations are done via a type called Calculator and it also knows what the shape of the public “interface” on that type is. These two types are fairly tightly bound together.

We could reduce that coupling a little by passing an instance of Calculator to the Statistics class and that’d be general goodness in the sense that;

  1. It would allow us to pass Calculator-derived types in the future rather than have Statistics hard-coded around the concrete type Calculator
  2. It stops the Statistics class having to make decision about when/where to instantiate a Calculator.

So, we can do;

class Statistics
{
  public Statistics(Calculator calculator)
  {
    this.calculator = calculator;
  }

and that makes it a little better. From my point of view though, it’d be better to pass Calculator as an interface here rather than a class type. Why?

  1. It removes the need for my Statistics component to have a reference to the assembly containing Calculator. It can simply reference the assembly containing the interface ( as can the assembly that contains Calculator ).
  2. Versioning of that interface between Calculator and Statistics becomes very explicit – i.e. it’s explicitly acknowledged that there’s an interface that Calculator implements that other components depend on.
  3. There’s more flexibility around implementing ICalculator in the sense that .NET allows for only one base class whereas it allows for implementing multiple interfaces. I can get tied into some knots if I choose to pass a Calculator to the Statistics type whereas I tend to avoid them if I pass an ICalculator.
  4. The Statistics class is abstracted from anything about the ICalculator implementation other than its pure interface – i.e. it knows nothing about the type that implements the interface other than the fact that it implements it. I suspect this is in at least some ways a restatement of the last point.

I’m sure there are others but I tend to have a strong interface bent that was beaten into my via COM, DCE and RPC so I tend to like interfaces.

So, we can then do;

  interface ICalculator
  {
    double Add(double x, double y);
    double Divide(double x, double y);
    double Multiply(double x, double y);
    double Root(double x);
    double Subtract(double x, double y);
  }

and that leaves our Calculator implementation as;

class Calculator : ICalculator
{
  public Calculator()
  {

  }
  public double Add(double x, double y) 
  { 
    return (x + y); 
  }
  public double Subtract(double x, double y) 
  { 
    return (x - y); 
  }
  public double Multiply(double x, double y) 
  { 
    return (x * y); 
  }
  public double Divide(double x, double y) 
  { 
    return (x / y); // Woops, Div/0.
  }
  public double Root(double x)
  {
    return (Math.Sqrt(x));
  }
}

and then our Statistics class just has;

class Statistics
{
  public Statistics(ICalculator calculator)
  {
    this.calculator = calculator;
  }
  public double StandardDeviation(params double[] values)
  {
    double average = 0;

    foreach (var item in values)
    {
      average = calculator.Add(average, item);
    }
    average = calculator.Divide(average, values.Length);

    double stdev = 0;

    foreach (var item in values)
    {
      double value = calculator.Subtract(average, item);
      value = calculator.Multiply(value, value);
      stdev = calculator.Add(stdev, value);
    }
    stdev = calculator.Divide(stdev, values.Length);

    return (calculator.Root(stdev));
  }
  ICalculator calculator;
}

and usage looks like;

  static void Main(string[] args)
  {
    Statistics s = new Statistics(new Calculator());

    Console.WriteLine(
      s.StandardDeviation(10, 20, 30, 40, 50, 60, 70, 80, 90, 100));
  }

Whilst I think the code ( or at least the structure of it ) has improved a little as I’ve gone along, there’s one part of what I’ve done which is really just pushing the problem around in that I now have my Main function and, somehow, that function magically just “knows” that the right type of ICalculator to use is Calculator. That’s still not-as-great-as-it-might-be.

What I could do is build some kind of lookup table that, given a particular interface like ICalculator, goes and looks up what the concrete implementation of that type should be for my particular program. That lookup table might be populated by code or configuration and there might be some rules around which takes precedence and so on.

I’d imagine that I might have some sort of interfaces onto that lookup table like;

public interface IRegisterTypes
{
  void RegisterType<INTERFACETYPE>(Type implementationType);
}

public interface ILocateTypes
{
  INTERFACETYPE GetInstance<INTERFACETYPE>();
  IEnumerable<INTERFACETYPE> GetAllInstances<INTERFACETYPE>();
}

Now, it probably needs to be more elaborate than this and, as usual, smart folks have already been here in that there’s a CodePlex project for a Common Service Locator library which includes an interface that does the location-side of this, IServiceLocator;

public interface IServiceLocator : IServiceProvider 
{ 
  object GetInstance(Type serviceType); 
  object GetInstance(Type serviceType, string key); 
  IEnumerable<object> GetAllInstances(Type serviceType); 
  
  TService GetInstance<TService>(); 
  TService GetInstance<TService>(string key); 
  IEnumerable<TService> GetAllInstances<TService>();    
}

So, where does Unity fit into all this? It’s a container that implements this interface and also handles the registration side of things and it does it in a pretty neat way. Going down a simplistic route first I might bring in references to Microsoft.Practices.Unity and then I could change my usage code to something like;

  static void Main(string[] args)
  {
    UnityContainer uc = new UnityContainer();

    uc.RegisterType(typeof(ICalculator), typeof(Calculator));

    Statistics s = new Statistics(uc.Resolve<ICalculator>());

    Console.WriteLine(
      s.StandardDeviation(10, 20, 30, 40, 50, 60, 70, 80, 90, 100));
  }

Ok, so this isn’t much more clever than it was before. I’m using Main to register with Unity that the type that implements ICalculator is currently Calculator and then when it comes time to pass an ICalculator to the constructor for Statistics I use Unity to find me the type that I’m using for ICalculator.

However, Unity is smart than this. Much smarter. Here’s that usage code again reworked.

 static void Main(string[] args)
  {
    UnityContainer uc = new UnityContainer();

    uc.RegisterType(typeof(ICalculator), typeof(Calculator));

    Statistics s = uc.Resolve<Statistics>();

    Console.WriteLine(
      s.StandardDeviation(10, 20, 30, 40, 50, 60, 70, 80, 90, 100));
  }

Notice line 7. I’m no longer creating any Calculator instances and nor am I asking Unity to resolve ICalculator for me to produce something that looks like an ICalculator.

I’m simply asking Unity to give me a Statistics instance and yet the code still works. Unity spots that Statistics has a constructor that takes an ICalculator so it assumes that Statistics has a dependency on ICalculator ( which it does ) and so it hands it an instance of Calculator at construction time. If the Statistics class had a constructor that looked like this;

  public Statistics(UnityContainer container, ICalculator calculator)
  {
    this.calculator = calculator;
  }

then Unity would prefer that one and would pass the UnityContainer to the constructor call alongside the ICalculator. A more advanced use of containers is to nest them and being able to get hold of the “right” container can be useful to a component like Statistics here.

I can move the registration of the link between ICalculator and Calculator into a configuration file (e.g.) as in;

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity"
             type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
  </configSections>
  <unity>
    <containers>
      <container>
        <types>
          <type type="Interface.ICalculator, Interface"
                mapTo="Implementation.Calculator, Implementation"/>
        </types>
      </container>
    </containers>
  </unity>
</configuration>

and then the usage code gets reduced down to;

  static void Main(string[] args)
  {
    UnityConfigurationSection config = 
      (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

    IUnityContainer container = new UnityContainer();

    config.Containers.Default.Configure(container);

    Statistics s = container.Resolve<Statistics>();

    Console.WriteLine(
      s.StandardDeviation(10, 20, 30, 40, 50, 60, 70, 80, 90, 100));
  }

and so now we’ve got a Main that doesn’t know a thing about Calculator or ICalculator and we’ve got Statistics that only knows about ICalculator and has no idea where the implementation comes from :-)

We don’t have to go via the constructor route though. We could re-work Statistics to have a property for the ICalculator;

class Statistics
{
  [Dependency]
  public ICalculator Calculator { get; set; }

  public double StandardDeviation(params double[] values)
  {
    double average = 0;

    foreach (var item in values)
    {
      average = Calculator.Add(average, item);
    }
    average = Calculator.Divide(average, values.Length);

    double stdev = 0;

    foreach (var item in values)
    {
      double value = Calculator.Subtract(average, item);
      value = Calculator.Multiply(value, value);
      stdev = Calculator.Add(stdev, value);
    }
    stdev = Calculator.Divide(stdev, values.Length);

    return (Calculator.Root(stdev));
  }
}

and the usage code doesn’t have to change at all – Unity will inject an instance of the right Calculator type into that property as/when we ask it to resolve our Statistics instance for us. Speaking of instancing, at present we’re allowing Unity to always create us a new calculator so if we do something like;

  static void Main(string[] args)
  {
    UnityConfigurationSection config = 
      (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

    IUnityContainer container = new UnityContainer();

    config.Containers.Default.Configure(container);

    for (int i = 0; i < 5; i++)
    {
      Statistics s = container.Resolve<Statistics>();
    }    
  }

then we’ll find that 5 Calculator instances get constructed. That might not be the right thing to do and so we could either register a specific instance as in;

  static void Main(string[] args)
  {
    UnityConfigurationSection config =
      (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

    IUnityContainer container = new UnityContainer();

    config.Containers.Default.Configure(container);

    container.RegisterInstance<ICalculator>(new Calculator());

    for (int i = 0; i < 5; i++)
    {
      Statistics s = container.Resolve<Statistics>();
    }
  }

where on line 10 we RegisterInstance of a particular Calculator so that’s the one and only Calculator that’ll get created there or we can configure a lifetime manager that decides what to do about construction as in;

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity"
             type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
  </configSections>
  <unity>
    <containers>
      <container>
        <types>
          <type type="Interface.ICalculator, Interface"
                mapTo="Implementation.Calculator, Implementation">
            <lifetime type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager,
               Microsoft.Practices.Unity"/>
          </type>
        </types>
      </container>
    </containers>
  </unity>
</configuration>

and now ( because of the ContainerControlledLifetimeManager ) I’ll only end up with one Calculator again. There are other lifetime managers offering things like per-thread instantiation and other variations plus ( of course ) you can plug in your own.

What if I already had a Statistics instance rather than asking Unity to resolve one for me – can Unity still help? Yep…

  static void Main(string[] args)
  {
    UnityConfigurationSection config =
      (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

    IUnityContainer container = new UnityContainer();

    config.Containers.Default.Configure(container);

    Statistics existingInstance = new Statistics();
    container.BuildUp(existingInstance);

    Console.WriteLine(
      existingInstance.StandardDeviation(10, 20, 30, 40, 50, 60, 70, 80, 90, 100));
  }

Notice on line 11 that we BuildUp an existing instance thereby injecting the things that it needs and so the call on line 14 doesn’t result in a null reference exception due to the lack of an ICalculator but does, instead, work :-)

Now, all of this would be less cool if it didn’t recurse down the hierarchy of objects that we’re building up. Imagine that my Calculator wants to do some logging via a logging class;

namespace Implementation
{
  public class Logger : ILog
  {
    public void Log(string text)
    {
      Console.WriteLine(text);
    }
  }
}

which it uses via an interface;

namespace Interface
{
  public interface ILog
  {
    void Log(string text);
  }
}

and the implementation uses it and marks it as a dependency;

class Calculator : ICalculator
  {
    public Calculator()
    {

    }
    
    [Dependency]
    public ILog Logger { get; set; }

    public double Add(double x, double y)
    {
      Logger.Log(string.Format("Add called with {0},{1}", x, y));

      return (x + y);
    }
    public double Subtract(double x, double y)
    {
      Logger.Log(string.Format("Subtract called with {0},{1}", x, y));
      return (x - y);
    }
    public double Multiply(double x, double y)
    {
      Logger.Log(string.Format("Multiply called with {0},{1}", x, y));
      return (x * y);
    }
    public double Divide(double x, double y)
    {
      Logger.Log(string.Format("Divide called with {0},{1}", x, y));
      return (x / y); // Woops, Div/0.
    }
    public double Root(double x)
    {
      Logger.Log(string.Format("Root called with {0}", x));
      return (Math.Sqrt(x));
    }
  }

and so I can change my configuration;

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity"
             type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
  </configSections>
  <unity>
    <containers>
      <container>
        <types>
          <type type="Interface.ICalculator, Interface"
                mapTo="Implementation.Calculator, Implementation"/>
          <type type="Interface.ILog,Interface"
                mapTo="Implementation.Logger,Implementation">
            <lifetime type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager,
               Microsoft.Practices.Unity"/>
          </type>
        </types>
      </container>
    </containers>
  </unity>
</configuration>

Note that I decided that I don’t mind there being many instances of my Calculator but I probably do only want a single Logger and so it’s configured that way and then the usage code remains as;

 static void Main(string[] args)
  {
    UnityConfigurationSection config =
      (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

    IUnityContainer container = new UnityContainer();

    config.Containers.Default.Configure(container);

    Statistics instance = container.Resolve<Statistics>();

    Console.WriteLine(
      instance.StandardDeviation(10, 20, 30, 40, 50, 60, 70, 80, 90, 100));
  }

And my Statistics instance gets the right Calculator and my Calculator gets the right Logger and life’s good :-) - the framework recurses down to build up the hierarchy.

Now, it’s possible to register more than one instance of the same type with the same container and it’s possible to have more than one container and it’s possible to do that in code or pre-bake it into config. So, maybe I implement a new Logger that logs everything in green;

  public class GreenLogger : ILog
  {
    public void Log(string text)
    {
      Console.ForegroundColor = ConsoleColor.Green;
      Console.WriteLine(text);
      Console.ResetColor();
    }
  }

and then I can configure 2 lumps of configuration in my config file;

<configuration>
  <configSections>
    <section name="unity"
             type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
  </configSections>
  <unity>
    <typeAliases>
      <typeAlias alias="singleton"
                 type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity"/>
    </typeAliases>
    <containers>
      <container name="regular">
        <types>
          <type type="Interface.ICalculator, Interface"
                mapTo="Implementation.Calculator, Implementation"/>
          <type type="Interface.ILog,Interface"
                mapTo="Implementation.Logger,Implementation">
            <lifetime type="singleton"/>
          </type>
        </types>
      </container>
      <container name="green">
        <types>
          <type type="Interface.ICalculator, Interface"
                mapTo="Implementation.Calculator, Implementation"/>
          <type type="Interface.ILog,Interface"
                mapTo="Implementation.GreenLogger,Implementation">
            <lifetime type="singleton"/>
          </type>
        </types>
      </container>
    </containers>
  </unity>
</configuration>

and pull them out by name – first configuring to use my regular Logger and then switching to use my GreenLogger;

  static void Main(string[] args)
  {
    UnityConfigurationSection config =
      (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

    IUnityContainer container = new UnityContainer();

    config.Containers["regular"].Configure(container);

    Statistics instance = container.Resolve<Statistics>();

    // Regular logging...
    Console.WriteLine(
      instance.StandardDeviation(10, 20, 30, 40, 50, 60, 70, 80, 90, 100));
    
    config.Containers["green"].Configure(container);
    container.BuildUp(instance);

    // Green logging...
    Console.WriteLine(
      instance.StandardDeviation(10, 20, 30, 40, 50, 60, 70, 80, 90, 100));
  }

I can also have a single container with multiple types registered for an interface and then differentiate them by name as we did with the containers. That is…I can do something like;

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity"
             type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
  </configSections>
  <unity>
    <containers>
      <container>
        <types>
          <type type="Interface.ICalculator, Interface"
                mapTo="Implementation.Calculator, Implementation"/>
          <type name="regular" 
                type="Interface.ILog,Interface"
                mapTo="Implementation.Logger,Implementation">
          </type>
          <type name="green" 
                type="Interface.ILog,Interface"
                mapTo="Implementation.GreenLogger,Implementation">
          </type>
        </types>
      </container>
    </containers>
  </unity>
</configuration>

and then write code against it to resolve ICalculator to either of those 2 registered implementations on lines 13 and 17 by specifying the name of the implementation that I want as in;

    UnityConfigurationSection config =
      (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

    IUnityContainer container = new UnityContainer();

    config.Containers.Default.Configure(container);

    ILog logger = container.Resolve<ILog>("regular");
    ILog greenLogger = container.Resolve<ILog>("green");

What I don’t know how to do is to have that apply when I build up a type like Statistics with its dependency on ILog – that is, how to specify which of the choice of registered loggers that I’ve got within the one container I want to use. That is, I can write this kind of code against the previous config;

  static void Main(string[] args)
  {
    UnityConfigurationSection config =
      (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

    IUnityContainer container = new UnityContainer();

    config.Containers.Default.Configure(container);

    Statistics statistics = container.Resolve<Statistics>("green");
  }

but that doesn’t work in that it doesn’t take that label “green” and apply it down the hierarchy as it does the dependency injection of the ILog into the Calculator property Logger.

I’m not quite sure how you go about that at the time of writing but it might be a case where I’d want to nest containers rather than trying to take this approach.

In terms of nesting, I could have a configuration such as;

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity"
             type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
  </configSections>
  <unity>
    <containers>
      <container>
        <types>
          <type type="Interface.ICalculator, Interface"
                mapTo="Implementation.Calculator, Implementation"/>
          <type 
                type="Interface.ILog,Interface"
                mapTo="Implementation.Logger,Implementation">
          </type>
        </types>
      </container>
    </containers>
  </unity>
</configuration>

with just a single implementation of ILog configured. Bringing that into code I might have;

  static void Main(string[] args)
  {
    UnityConfigurationSection config =
      (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

    IUnityContainer container = new UnityContainer();

    config.Containers.Default.Configure(container);

    IUnityContainer childContainer = container.CreateChildContainer();

    Statistics statistics = childContainer.Resolve<Statistics>();

    Console.WriteLine(statistics.StandardDeviation(10, 20, 30, 40, 50));
  }

Note here that on line 12 we use the childContainer to resolve the Statistics type. The childContainer does not have a type registered for ILog but it doesn’t matter, it just defers to its parent to find out what to do about it. However, if we change the childContainer to have a registered type for ILog then it will prefer that one and so this code;

  static void Main(string[] args)
  {
    UnityConfigurationSection config =
      (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

    IUnityContainer container = new UnityContainer();

    config.Containers.Default.Configure(container);

    IUnityContainer childContainer = container.CreateChildContainer();

    childContainer.RegisterType(typeof(ILog), typeof(GreenLogger));

    Statistics statistics = childContainer.Resolve<Statistics>();

    Console.WriteLine(statistics.StandardDeviation(10, 20, 30, 40, 50));
  }

on line 12 registers a GreenLogger as the ILog implementation in the childContainer and so that means that my Statistics instance will have a GreenLogger injected as the value of its Logger property when it is resolved by the container whereas if we did;

  static void Main(string[] args)
  {
    UnityConfigurationSection config =
      (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

    IUnityContainer parentContainer = new UnityContainer();

    config.Containers.Default.Configure(parentContainer);

    IUnityContainer childContainer = parentContainer.CreateChildContainer();

    childContainer.RegisterType(typeof(ILog), typeof(GreenLogger));

    Statistics statistics = parentContainer.Resolve<Statistics>();

    Console.WriteLine(statistics.StandardDeviation(10, 20, 30, 40, 50));
  }

then because line 14 is using the parentContainer it’d end up with a Logger rather than a GreenLogger because that’s what is registered with the parent container – fairly natural scoping rules that seem intuitive to me.

So, that’s a bit of a whistle-stop tour of some of the things that Unity can do.

The benefits are probably fairly obvious with one of the key ones being around the ability to inject different (potentially mock) sub-components as a means of testing your component in isolation from those that it depends upon.

There are some more tricks that Unity has up its sleeve though and I’ll see if I can back to some of those in a follow on post. As usual, if you spot errors let me know and I’ll fix them.


Posted Mon, Aug 10 2009 4:43 PM by mtaulty
Filed under:

Comments

NewsPeeps wrote Rough Notes on Unity
on Tue, Aug 11 2009 8:41 AM

Thank you for submitting this cool story - Trackback from NewsPeeps

tom wrote re: Rough Notes on Unity
on Tue, Aug 11 2009 10:50 AM

Thanks Mike

Very informative - I'm still trying to 'grok' the whole DI/IoC thing and this definately helps.

Tom

Duncan Smart wrote re: Rough Notes on Unity
on Tue, Aug 11 2009 11:26 AM

I think the main point is *isolation for testing*, all the other benefits are just gravy. I just thought "WTF?" until I realised this.

ajit goel wrote re: Rough Notes on Unity
on Sun, Aug 16 2009 8:54 PM

Thanks Mark;

This is an exceptional article. first time in a year have I understood what dependency injection actually meant, what its advantages were and how to "do it in" code.

Will Rogers wrote re: Rough Notes on Unity
on Mon, Aug 17 2009 5:25 AM

Thanks Mike! This is just the introduction I've been looking for.

Anonymous wrote re: Rough Notes on Unity
on Mon, Aug 17 2009 10:24 AM

lol! wut?

Benni wrote re: Rough Notes on Unity
on Tue, Aug 18 2009 1:23 AM

Thanks for the post Mike. I've been a little bewildered with Unity's documentation, but your descriptions are really helpful.