2

I am using Unity as IOC and trying to inject an interface with a factory method which takes a interface as a parameter.

For some reason the configReader parameter in the factory method GetTitleParser(), is null and not getting the injected ConfigurationReader() instance.

When i place a debug point at the line in RegisterTypes method where the new InjectionFactory exists, ITitleParser is not showing as mapped to a proper mapped type.

can anyone help what am i doing wrong here?

Here is my code:

public class UnityContainerBuilder
{
    public static IUnityContainer Build()
    {
        var container = new UnityContainer();
        RegisterTypes(container);
        return container;
    }

    public static void RegisterTypes(IUnityContainer container)
    {
        // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
        container.LoadConfiguration();
        container.RegisterType<IConfigurationReader, ConfigurationReader>();
        container.RegisterType<ITitleParser>(new InjectionFactory(c => ParserFactory.GetTitleParser()));            
    }
}

public class ParserFactory
{
    public static ITitleParser GetTitleParser(IConfigurationReader configReader=null)
    {
        if(configReader==null) configReader = new ConfigurationReader();

        /* rest of code here...*/

        return parser;
    }
}   

It works when i use the following code. Is this the right way to do this?

    container.RegisterType<IConfigurationReader, ConfigurationReader>();
    container.RegisterType<ITitleParser>(new InjectionFactory(c =>
                                                                {
                                                                    var configReader = c.Resolve<IConfigurationReader>();
                                                                    var parser = ParserFactory.GetTitleParser(configReader);
                                                                    return parser;
                                                                }));

2 Answers 2

3

When you use default parameters it's equal to:

container.RegisterType<ITitleParser>(
    new InjectionFactory(c => ParserFactory.GetTitleParser(null)));

Because, compiler inserts all default values in method calls (null in your case).

So, your code is valid:

container.RegisterType<ITitleParser>(new InjectionFactory(c =>
{
    var configReader = c.Resolve<IConfigurationReader>();
    var parser = ParserFactory.GetTitleParser(configReader);
    return parser;
}));

But i advice you to remove default value to make code more expressive.

Sign up to request clarification or add additional context in comments.

Comments

1

Your code is valid but maybe you can avoid messing up with InjectionFactory parameters and ParserFactory.

 public class UnityContainerBuilder
    {
        public static IUnityContainer Build()
        {
            var container = new UnityContainer();
            RegisterTypes(container);
            return container;
        }

        public static void RegisterTypes(IUnityContainer container)
        {
            // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
            container.LoadConfiguration();
            container.RegisterType<IConfigurationReader, ConfigurationReader>();
            container.RegisterInstance<IAppConfig>(container.Resolve<IConfigurationReader>().ReadConfiguration());
            container.RegisterType<ITitleParser, TitleParser>();            
        }
    }

    public class AppConfig: IAppConfig
    {
        public AppConfig(){}
        //value1 property
        //value2 property
        //etc
    }   


    public class ConfigurationReader: IConfigurationReader
    {
        public ConfigurationReader(){}
        public IAppConfig ReadConfiguration(){
            var currentConfig = new AppConfig();
            //read config from file, DB, etc and init currentCongif
            return currentConfig;
        }
    }   

    public class TitleParser : ITitleParser
    {
        public TitleParser(IAppConfif)
        {
            //config already readed, just do the work       
        }
    }   

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.