Search code examples
c#unity-container

Unity container - resolve object which always same constructor parameter


I want to have only one instance of TestClass in my code. This class needs string parameter. Question is that, how can I register this object to unity container with string parameter once in UnityConfig class and then resolving this object everywhere in code? I tried it like this but during resolving I am getting exception.

This is my class:

    public class TestClass
    {
        public TestClass(string str)
        {
            message = str;
        }

        private string message;

        public string Message
        {
            get => message;
            set
            {
                message = value;
            }
        }
    }

And this is my UnityConfig class:

    public class UnityConfig
    {
        private readonly UnityContainer unityContainer;

        public UnityConfig()
        {
            unityContainer = new UnityContainer();
            unityContainer.RegisterType<TestClass>(new InjectionConstructor("Injected string"));
            var unityServiceLocator = new UnityServiceLocator(unityContainer);
            ServiceLocator.SetLocatorProvider(() => unityServiceLocator);
        }
    }

I am resolving it like this:

var serviceLocator = (UnityServiceLocator)ServiceLocator.Current;
var unityContainer = (UnityContainer)serviceLocator.GetService(typeof(UnityContainer));
var testClass = unityContainer.Resolve<TestClass>();

and then I am getting this exception:

Unhandled Exception:

Microsoft.Practices.Unity.ResolutionFailedException: Resolution of the dependency failed, type = "SpotFinder.ViewModels.TestClass", name = "(none)".

Exception occurred while: while resolving.

Exception is: InvalidOperationException - The type String cannot be constructed. You must configure the container to supply this value.


At the time of the exception, the container was:

Resolving SpotFinder.ViewModels.TestClass,(none)
Resolving parameter "str" of constructor SpotFinder.ViewModels.TestClass(System.String str)
Resolving System.String,(none)

I tried also register like this:

unityContainer.RegisterType<TestClass>(new InjectionConstructor(
                new InjectionParameter("Injected string"))
            );

Solution

  • You get new instance of UnityContainer using GetService(typeof(UnityContainer)) that doesn't have TestClass registration, so it give you a exception during resolve. Just use directly serviceLocator to resolve TestClass. It looks like this:

    var serviceLocator = (UnityServiceLocator)ServiceLocator.Current;
    var testClass = serviceLocator.GetService(typeof(TestClass));
    

    And registration:

    var unityContainer = new UnityContainer();
    // Configure only one instance of testclass
    unityContainer.RegisterType<TestClass>(new ContainerControlledLifetimeManager(), new InjectionConstructor("Injected string"));
    var unityServiceLocator = new UnityServiceLocator(unityContainer);
    ServiceLocator.SetLocatorProvider(() => unityServiceLocator);
    

    P.S. I don't suggest you to use ServiceLocator, you can look some his advantages/disadvantages