Mukil Deepthi
Mukil Deepthi

Reputation: 6482

C# Unity InjectionFactory not working

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;
                                                                }));

Upvotes: 2

Views: 6245

Answers (2)

Backs
Backs

Reputation: 24913

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.

Upvotes: 3

jlvaquero
jlvaquero

Reputation: 8785

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       
        }
    }   

Upvotes: 1

Related Questions