tags:

views:

992

answers:

2

Unity's documentation says of the RegisterInstance<> method that registers an instance so that that particular instance is returned everytime Resolve<> is called.

However, this example below shows that each time Resolve<> is called, a new instance of the type is returned.

Why is this?

using System;
using System.Windows;
using Microsoft.Practices.Unity;

namespace TestUnity34
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            Validator validator1 = new Validator();
            IUnityContainer container = new UnityContainer();
            container.RegisterInstance<IValidator>(validator1);

            Validator validatorCopied = validator1;
            Console.WriteLine(validator1.GetHashCode()); //14421545
            Console.WriteLine(validatorCopied.GetHashCode()); //14421545

            Validator validator2 = container.Resolve<Validator>();
            Console.WriteLine(validator2.GetHashCode()); //35567111

            Validator validator3 = container.Resolve<Validator>();
            Console.WriteLine(validator3.GetHashCode()); //65066874
        }
    }

    interface IValidator
    {
        void Validate();
        string GetStatus();
    }

    public class Validator : IValidator
    {
        public void Validate() { }

        public string GetStatus() { return "test"; }
    }
}
+2  A: 

I think if you called Resolve with IValidator as the type parameter, it would work as you expect:

...
var validator2 = container.Resolve<IValidator>();
...
Daniel Pratt
If I do that I get "Cannot implicitly convert type TestUnity34.IValidator' to 'TestUnity34.Validator'".
Edward Tanguay
The short answer is, when you are referencing objects retrieved from the IoC container, used the registered type (IValidator) rather than the concrete type (Validator).
Daniel Pratt
+5  A: 

You have configured your container with IValidator so you will have to resolve using IValidator instead of Validator:

Validator validator1 = new Validator(); 
IUnityContainer container = new UnityContainer(); 
container.RegisterInstance<IValidator>(validator1); 
Validator validatorCopied = validator1; 
Console.WriteLine(validator1.GetHashCode());
Console.WriteLine(validatorCopied.GetHashCode());
IValidator validator2 = container.Resolve<IValidator>();            
Console.WriteLine(validator2.GetHashCode());             
IValidator validator3 = container.Resolve<IValidator>();            
Console.WriteLine(validator3.GetHashCode());

Alternatively you can keep your registration using Validator but then you have to resolve using Validator as well:

Validator validator1 = new Validator();
IUnityContainer container = new UnityContainer();
container.RegisterInstance<Validator>(validator1);
Validator validatorCopied = validator1;
Console.WriteLine(validator1.GetHashCode());
Console.WriteLine(validatorCopied.GetHashCode());
Validator validator2 = container.Resolve<Validator>();
Console.WriteLine(validator2.GetHashCode());
Validator validator3 = container.Resolve<Validator>();
Console.WriteLine(validator3.GetHashCode());
Jakob Christensen
yes that was it, thanks!
Edward Tanguay