2012-05-02 59 views
3

嗨,我是新来的温莎城堡,我努力了解一些基础知识,所以我想我发布一个问题,而不是通过代码,希望能尽快解决我的问题。自定义配置注入 - 新城堡温莎/ IoC

我有一个web服务,需要从配置文件web.config中提取信息。此信息位于自定义配置部分,我想知道如何将该信息传达给需要它的课程。 我不想将该类绑定到配置文件,因为我可能通过IIS或自定义Windows服务来承载此类。我第一次尝试是做这样的事情:

iocCon.Register(Component.For<ErrorMessagesSection>().LifeStyle.Singleton.Instance(FindConfigSection<ErrorMessagesSection>())); 

private T FindConfigSection<T>() where T : ConfigurationSection 
    { 
     System.Configuration.Configuration config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("/web.config");//TODO: remove this hard coding to iis hosting .OpenExeConfiguration(ConfigurationUserLevel.None); 
     ConfigurationSectionGroupCollection sectionGroups = config.SectionGroups; 

     foreach (ConfigurationSectionGroup sectionGroup in sectionGroups) 
      foreach (ConfigurationSection configurationSection in sectionGroup.Sections) 
       if (configurationSection.GetType() == typeof(T)) 
        return (T) configurationSection; 
     return null; 
    } 

的部分只能定义一次,所以这基本上抓住部分,因此它可以被注入到一个错误消息工厂类的构造函数。这不会引发任何错误,但我注意到该部分被创建两次,这是导致其他问题(我应该修复,但...)无论如何,以解决这个问题我决定我会创建单个实例并自己注册所以我尝试:

UGLY_HACK = new ConfigFileErrorMessageManager(eMessages); 
iocContationer.Register(Component.For<IErrorMessageManager>().ImplementedBy<ConfigFileErrorMessageManager>().LifeStyle.Singleton.Instance(UGLY_HACK)); 

这是一个刚刚创建的容器,先登记,并将其与以下炸毁:

[ComponentRegistrationException: This component has already been assigned implementation xxx.ConfigFileErrorMessageManager] 
Castle.MicroKernel.Registration.ComponentRegistration`1.ImplementedBy(Type type,  IGenericImplementationMatchingStrategy genericImplementationMatchingStrategy) +310 

Castle.MicroKernel.Registration.ComponentRegistration`1.Instance(TService instance) +44 

我的第一个问题:如何为这个错误可能的(没有别的一直注册)/还是这意味着比看起来更微妙的东西?第二个问题:获取需要它的类的配置信息的最佳实践是什么(我是否正在讨论这个错误)?

感谢您的帮助

回答

4

好像你真正需要的是一个ConfigurationManager适配器,将允许您注册的配置与温莎应用。

Here's an IConfigurationManager implementation带有适配器WebConfigurationManager,可以让你做到这一点。

要注册

container.Register(
    Component.For<IConfigurationManager>() 
      .Instance(new WebConfigurationManagerAdapter())); 

现在,你可以注入IConfigurationManager到需要访问配置组件。

如果你只是想注入的特定部分,你可以注册一个工厂方法与温莎检索从例如容器注册的IConfigurationManager强类型节像

container.Register(
    Component.For<ErrorMessagesSection>() 
      .UsingFactoryMethod(kernel => 
       kernel.Resolve<IConfigurationManager>() 
         .GetSection<ErrorMessagesSection>("errorSectionName"))); 
+1

感谢拉斯,我喜欢这个想法比我所做的更多,所以我做了改变,做了一些其他改变后,我得到了它的一切工作。我真的很想理解我得到的错误,我不喜欢不理解为什么发生了什么事情,我真的没有时间翻阅windsor的源文件,所以如果你对错误有任何想法,我会很感激他们。 –

+0

@Justin您遇到的错误对我来说,与您使用'ImplementedBy <>'和'Instance()'为IErrorMessageManager服务注册一个组件事实上,你实际上只需要一个(并且因此涉及多个注册的异常消息)。它看起来像你只想要'Instance()'这将约定注册传递的实例作为一个单身。 –

+1

就是这样。非常感谢Russ。 –