Search code examples
c#inversion-of-controlprismioc-container

How to register service as transient in Prism


Recently I have used the Prism.DryIoC library into the WPF project. I discovered in App.xaml.cs class to override a RegisterTypes method

using Prism.Ioc;
using WpfAppNetCore.Views;
using System.Windows;

namespace WpfAppNetCore
{
    public partial class App
    {
        protected override Window CreateShell()
        {
            return Container.Resolve<MainWindow>();
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            // Register as Singleton 
            containerRegistry.RegisterSingleton<ITest, Test>();
        }
    }
}

I have an implementation of a class that inherits from the ITest interface as follows:

ITest.cs

namespace WpfAppNetCore
{
    public interface ITest
    {
        string GetTime { get; set; }
    }
}

Test.cs

using System;

namespace WpfAppNetCore
{
    public class Test : ITest
    {
        #region Implementation of ITest

        public string GetTime { get; set; } = $"{DateTime.Now:dd/MM/yyyy HH:mm:ss.ffff}";

        #endregion
    }
}

In a ViewModel I have called the GetTime property in ITest, and passed through the for loop.

public MainWindowViewModel(ITest test)
        {
            var sb = new StringBuilder();

            for (var i = 0; i < 10; i++)
            {
                sb.AppendLine(test.GetTime);
                Thread.Sleep(100);
            }

            Message = sb.ToString();
        }

If I register for ITest as a Singleton service, I will get the same result, which is true to my intention.

But I don't know how to register ITest as a Transient Scope service to get different results after each iteration.


Solution

  • This appears to be an XY problem.

     public string GetTime { get; set; } = $"{DateTime.Now:dd/MM/yyyy HH:mm:ss.ffff}";
    

    The above will only set the initial value of that property when the parent object is initialized.

    In this example

    public MainWindowViewModel(ITest test) {
        var sb = new StringBuilder();
    
        for (var i = 0; i < 10; i++) {
            sb.AppendLine(test.GetTime);
            Thread.Sleep(100);
        }
    
        Message = sb.ToString();
    }
    

    The same initial value will be returned in the loop whether the injected dependency is singleton or transient.

    According to source code repository, simply calling Register

    protected override void RegisterTypes(IContainerRegistry containerRegistry) {
        // Register as Transient
        containerRegistry.Register<ITest, Test>();
    }
    

    will register the mapped type as transient.