Search code examples
c#mvvm-lightsimpleioc

what happened when MVVMLight SimpleIoc registered multiple times?


I'd like to know when .Register() is performed multiple times. Based on my experiment, below Console.WriteLine gives same Init value.

So, does .Register() check already registered instance and ignore to re-register?

void Main()
{
    // #1
    SimpleIoc.Default.Register<TestClass>();
    Console.WriteLine(SimpleIoc.Default.GetInstance<TestClass>().Init);

    // #2   
    SimpleIoc.Default.Register<TestClass>();
    Console.WriteLine(SimpleIoc.Default.GetInstance<TestClass>().Init);

    // Result: #1 and #2 give identical Init value.
}

public class TestClass
{
    public string Init { get; set;}
    public TestClass()
    {
        Init = Guid.NewGuid().ToString();
    }
}

Solution

  • If look at source code of Register method by decompiling it (in case you cannot find \ don't want to bother with actual source code), you will see (with irrelevant parts skipped):

    public void Register<TClass>(bool createInstanceImmediately) where TClass : class
    {
      Type index = typeof (TClass);
      // skipped irrelevant parts
      if (this._factories.ContainsKey(index) && this._factories[index].ContainsKey(this._defaultKey))
      {
         if (!this._constructorInfos.ContainsKey(index))
           throw new InvalidOperationException(string.Format((IFormatProvider) CultureInfo.InvariantCulture, "Class {0} is already registered.", (object) index));
      } else {
          if (!this._interfaceToClassMap.ContainsKey(index))
            this._interfaceToClassMap.Add(index, (Type) null);
          this._constructorInfos.Add(index, this.GetConstructorInfo(index));
          Func<TClass> factory = new Func<TClass>(this.MakeInstance<TClass>);
          this.DoRegister<TClass>(index, factory, this._defaultKey);
          if (!createInstanceImmediately)
            return;
          this.GetInstance<TClass>();
        }
      }
    }
    

    So, if there is already registered factory in _factories dictionary - it checks if there is constructor info registered for this type and if NOT - throws exception about already registered class. I suppose this is a typo and check should be reversed - if there IS already registered constructor (which you register in else block) - there should be exception about already registered class. But as it is implemented now - it just does nothing when you try to register second time.