2016-03-02 86 views
2

我有依赖字符串列表上的组件:Castle Windsor:如何将appSettings依赖项转换为列表或数组?

// ctor 
public MyComponent(IList<string> someStrings) { ... } 

使用温莎城堡,我想提供文件,像这样从我的app.config的AppSettings节这种依赖关系:

container.Register(Component 
    .For<IMyComponent>() 
    .ImplementedBy<MyComponent>() 
    .DependsOn(Dependency.OnAppSettingsValue("someStrings", "SomeStrings")) 
); 

Inline Dependencies温莎文件说:

appSettings and conversion:配置文件中的值以文本形式存储,但代码中的依赖项可能是其他类型(本例中为TimeSpan)。温莎已经涵盖了你,并且大多数情况下会为你执行适当的转换。

  1. 是否涵盖我这情况下,我想转换为IList<string>
  2. 如果是这样,在app.config文件中输入字符串列表的正确方法是什么?
  3. 如果没有,是否有可扩展性点,我可以指定我自己的转换?

回答

1

这里面临的一个更大的问题是,在appSettings中存储值列表并不重要。 This question addresses it,最好的答案是在设置文件中创建您自己的部分,然后您必须通过ConfigurationManager.GetSection()而不是ConfigurationManager.AppSettings.Get(),which is what Dependency.OnAppSettingsValue() uses访问该部分。纵观Dependency课程的其余部分,似乎没有内置的方法来完成此任务。

但是,如果它真的只是你需要的字符串,你至少有两个选项并不全是坏的(在我看来)。

1.使用StringCollection将字符串存储在App.config文件中。

这只是在App.config中创建自己的部分的一个较短的内置版本。使用Visual Studio的“项目属性”页面中的编辑器添加StringCollection类型的应用程序设置。这会让你看起来的App.config像这样的东西:在配置组件时

<configuration> 
    <configSections> 
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" > 
     <section name="YourApplication.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> 
    </sectionGroup> 
    </configSections> 
    <applicationSettings> 
    <YourApplication.Properties.Settings> 
     <setting name="SomeStrings" serializeAs="Xml"> 
     <value> 
      <ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
      <string>one</string> 
      <string>two</string> 
      <string>three</string> 
      </ArrayOfString> 
     </value> 
     </setting> 
    </YourApplication.Properties.Settings> 
    </applicationSettings> 
</configuration> 

然后:

// StringCollection only implements IList, so cast, then convert 
var someStrings = Properties.Settings.Default.SomeStrings.Cast<string>().ToArray(); 
container.Register(Component.For<IMyComponent>() 
          .ImplementedBy<MyComponent>() 
          .LifestyleTransient() 
          .DependsOn(Dependency.OnValue<IList<string>>(someStrings))); 

2.存储的字符串作为分隔列表中appSettings,然后手动将它们分割。

这很可能是更简单的方法,但假设你可以计算出你的字符串分隔符(可能并非总是如此)。将值添加到您的应用程序。配置文件:

<configuration> 
    <appSettings> 
    <add key="SomeStrings" value="one;two;three;four" /> 
    </appSettings> 
</configuration> 

然后配置你的组件时:

var someStrings = ConfigurationManager.AppSettings["SomeStrings"].Split(';'); 
container.Register(Component.For<IMyComponent>() 
          .ImplementedBy<MyComponent>() 
          .LifestyleTransient() 
          .DependsOn(Dependency.OnValue<IList<string>>(someStrings))); 

在任何情况下,我们只是将工作对Dependency.OnValue顶部一个小数目,这是所有Dependency.OnAppSettingsValue做无论如何。

我觉得这个回答你的问题,但要明确:

  1. 是的,但你做你自己,所以你可以转换成任何你想要的转换。
  2. 查看链接的问题和accepted answer,或使用StringCollection
  3. Dependency.OnValue是延伸(在我看来),我不知道或看到任何其他地方你会这样做。但是,鉴于上述步骤,我不认为这是必要的。
+0

非常感谢您的详细解答 - 我现在选择了2。 – urig

+0

其实,我认为我的第一个问题的“是,但”答案是“不”。虽然Windsor允许我(开箱即用)在appSettings中添加TimeSpan值,但它不允许我对列表(或string [])的值做同样的处理。 我想知道Windsor将字符串值“反序列化”到TimeSpan的位置,看看它是否可以扩展到列表。 – urig

+0

convesions子系统看起来神奇发生的地方:https://github.com/castleproject/Windsor/blob/master/docs/subsystems.md但没有太多的文档可以找到。 – urig

相关问题