C#Unity InjectionFactory无法正常工作

时间:2016-07-05 08:52:53

标签: c#-4.0 asp.net-web-api unity-container

我使用Unity作为IOC并尝试使用工厂方法注入接口,该接口将接口作为参数。

由于某种原因,工厂方法GetTitleParser()中的configReader参数为null,并且没有获取注入的ConfigurationReader()实例。

当我将调试点放在RegisterTypes方法中存在新的InjectionFactory的行时,ITitleParser没有显示为映射到正确的映射类型。

任何人都可以帮助我在这里做错了吗?

这是我的代码:

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

当我使用以下代码时它可以工作。这是正确的方法吗?

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

2 个答案:

答案 0 :(得分:3)

使用默认参数时,它等于:

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

因为,编译器会在方法调用中插入所有默认值(在您的情况下为null)。

所以,你的代码是有效的:

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

但我建议您删除默认值以使代码更具表现力。

答案 1 :(得分:1)

您的代码有效,但也许您可以避免弄乱InjectionFactory参数和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       
        }
    }