我使用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;
}));
答案 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
}
}