February 12, 2015

Unity

Here are some helpful links: Here are some examples using the following simple classes:
interface ITextService
{
    string Text { get; set; }
}

internal class TextService : ITextService
{
    public string Text { get; set; }
}
With the simplest form of Unity registration, invoking 'Resolve' creates a new instance of the service each time
public void RegisterServiceNewInstanceEachTimeTest()
{
    IUnityContainer myContainer = new UnityContainer();

    myContainer.RegisterType<ITextService, TextService>();
    // Create a TestService instance
    ITextService svc1 = myContainer.Resolve<ITextService>();

    svc1.Text = "Doombar";
    // Creates a new TestService instance
    ITextService svc2 = myContainer.Resolve<ITextService>();
    Assert.AreNotEqual(svc1.Text, svc2.Text, false);
}
Resolve creates a new instance of the service each time however this time the service is registered against a string name or label that can be used to identify and retrieve it
public void RegisterNamedServiceNewInstanceEachTimeTest()
{
    IUnityContainer myContainer = new UnityContainer();

    myContainer.RegisterType<ITextService, TextService>("MyTextService");
    ITextService svc1 = myContainer.Resolve<ITextService>("MyTextService");
    svc1.Text = "Doombar";

    ITextService svc2 = myContainer.Resolve<ITextService>("MyTextService");
    Assert.AreNotEqual(svc1.Text, svc2.Text, false);
    Assert.IsFalse(ReferenceEquals(svc1, svc2));
}
A particular instance of a service object can be registered against the 'ITextService' type, this gives a way of registering singleton objects.
public void RegisterSpecificInstanceForServivceTest()
{
    IUnityContainer myContainer = new UnityContainer();
    TextService svc1 = new TextService();
    svc1.Text = "Doombar";

    myContainer.RegisterInstance<ITextService>(svc1);
    ITextService svc2 = myContainer.Resolve<ITextService>();

    Assert.AreEqual(svc1.Text, svc2.Text, false);
    Assert.IsTrue(ReferenceEquals(svc1, svc2));
}
Injection of service via a constructor First, define a demo class:
internal class ConstructorInjectedClass
{
    ITextService testSvc = null;

    public ConstructorInjectedClass(ITextService mysvc)
    {
        testSvc = mysvc;
        // work with the dependent instance
        testSvc.Text = "Yeehah!";
    }


    public ITextService TestService
    {
        get { return testSvc; }
    }
}
Now use Unity to perform the dependency injection:
public void ConstructorInjectionTest()
{
    IUnityContainer uContainer = new UnityContainer();
    uContainer.RegisterType<ITextService, TextService>();
    // Unity will look at all the objects required to construct the 'ConstructorInjectedClass'
    // object and automatically resolve them
    ConstructorInjectedClass myInstance = uContainer.Resolve<ConstructorInjectedClass>();
    Assert.IsNotNull(myInstance.TestService);
}
Multiple services can also be defined against a single type and retrieved:
public void ResolveAllTest()
{
    IUnityContainer uContainer = new UnityContainer();
    uContainer.RegisterType<ITextService, TextService>("textService1");
    uContainer.RegisterType<ITextService, DifferentTextService>("textService2");
    // Now there are 2 services registered as an ITextService
    // Use 'ResolveAll' to get all the services implementing the named type
    var textServices = uContainer.ResolveAll<ITextService>();
    int ix = 0;
    foreach (var ts in textServices)
    {
        ++ix;
        ts.Text = ix.ToString();
    }
    Assert.AreEqual(2, textServices.Count());
}
Perfect for the case when multiple logger services are used for logging, a debug output logger, a rolling file logger, and so on.