The feature
Unity 2.0 comes with new features. But the feature i want to talk about is "Automatic Factory". This feature is useful when one class has a dependency in another but may not need to have the instance of dependency in the constructor. Or, just want to create the dependency in another time.
Without "Automatic Factory" the solution was to pass a hard-coded factory to the class and create the dependency when needed. or inject the container in the class and use it to resolve the dependency. The former is tedious to do in every dependency you need. The later is making the class depend on the container only to not depend in another class. "Automatic Factory" will eliminate the problem to write factories and will finish the problem of propagating the container. First, a simple example:
class Calculator
{
public Calculator( Log log )
{
Console.WriteLine(log != null);
}
}
class Log
{
}
class Program
{
static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();
container.Resolve<Calculator>();
Console.ReadKey();
}
}
And the result is...

Ok. But so far there is no difference from Unity 1.2. So let´s make the creation of the log on the calculator a little bit more lazy.
class Calculator
{
public Calculator( Func<Log> newLog )
{
Console.WriteLine(newLog != null);
}
}
And now come the beauty of this new feature in Unity 2.0. The result is...

Yeah! Unity injected a factory in the calculator. Now the calculator can store this factory and only use it later. For example:
class Calculator
{
Func<Log> NewLog { get; set; }
Log Log { get; set; }
public Calculator(Func<Log> newLog)
{
NewLog = newLog;
}
public void EnsureLog()
{
if (Log == null)
{
Log = NewLog();
}
}
public void Run()
{
Console.WriteLine("Log == null : {0}", Log == null);
EnsureLog();
Console.WriteLine("Log == null : {0}", Log == null);
}
}
class Log
{
public Log()
{
Console.WriteLine("Building Log!");
}
}
class Program
{
static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();
var calculator = container.Resolve<Calculator>();
calculator.Run();
Console.ReadKey();
}
}
And the result is exactly as expected:

The Problem
So far so good... But, let´s say that the Log class has some parameters on it´s constructor. Something like the log´s file name.
class Log
{
public Log( string fileName )
{
Console.WriteLine("Building Log! {0}", fileName);
}
}
Ok... but now the log factory does not make any sense, let´s fix it.
public Calculator(Func<string, Log> newLog)
{
NewLog = newLog;
}
let´s run and...

We have a problem... Unity cannot inject factories when the dependency have constructor with parameters... hum...
The Solution
Luckily Unity is a extensible framework. So we can make a extension that will inject this factory ( can be downloaded from the bottom of the page ).
class Program
{
static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();
container.AddNewExtension<AutomaticFactoriesExtension>();
var calculator = container.Resolve<Calculator>();
calculator.Run();
Console.ReadKey();
}
}
Add the AutomaticFactoriesExtension to the Unity and now the example will work.

Unfortunately the extension is not working with abstract classes and interfaces. And that´s the reason that the factory in the calculator is returning the Log class and not ILog class. But this raise another questions. Make any sense to have a Func<string, ILog>? ILog does not have a constructor. And what happen if ILog have two or more concrete classes? The container should inject the right factory? Func<string, ILog>? Func<int, ILog>?
Important: This is only experimental code.
MachinaAurum.Unity.AutomaticFactories.dll.7z (4.33 kb)
