Search code examples
c#unity-container

RegisterInstance & TransientLifetimeManager, is it even possible?


Recently one of our development teams started with dependency injection.

One thing I noticed is that (when initializing the Container) the code has a lot of places, where it uses a TransientLifetimeManager on a instance. The instance has been created explicitly by the developer a few lines before.

KalenderView kalenderView = new KalenderView(new KalenderViewModel());
unityContainer.RegisterInstance(kalenderView, new TransientLifetimeManager());

Personally I would rewrite it into two RegisterType calls, one for the ViewModel, one for the View, but this got my attention.

My question is: Will the code even do, what I would expect it to do? It looks like it's creating a new object everytime a instance needs to be resolved (roughly explained). But that can't be right, can it? It would be "magic" for me, I don't think, unity can "analyse" and save the state of an object during registration, right?

I found nothing on whether it's possible to use TransientLifetimeManager on RegisterInstance. So, will it ignore the given manager and use the ContainerControlledLifetimeManager instead?


Solution

  • Let's write simple test:

    namespace UnityTest
    {
        using System;
        using Unity;
    
        class Program
        {
            public class TestClass
            {
                public static int Version = 0;
    
                public TestClass()
                {
                    Version++;
                    Console.WriteLine(Version);
                }
            }
    
            static void Main(string[] args)
            {
                var container = new UnityContainer();
    
                var obj = new TestClass();
    
                container.RegisterInstance(obj, new TransientLifetimeManager());
    
                container.Resolve<TestClass>();
                container.Resolve<TestClass>();
                container.Resolve<TestClass>();
            }
        }
    }
    

    Will output:

    1
    2
    3
    4
    

    So, container creates new instance per resolve.

    You can even remove registration and it will work:

    namespace UnityTest
    {
        using System;
        using Unity;
    
        class Program
        {
            public class TestClass
            {
                public static int Version = 0;
    
                public TestClass()
                {
                    Version++;
                    Console.WriteLine(Version);
                }
            }
    
            static void Main(string[] args)
            {
                var container = new UnityContainer();
    
                container.Resolve<TestClass>();
                container.Resolve<TestClass>();
                container.Resolve<TestClass>();
            }
        }
    }
    

    Will output:

    1
    2
    3