【问题标题】:Castle Windsor: How to convert an appSettings dependency to a list or an array?Castle Windsor:如何将 appSettings 依赖项转换为列表或数组?
【发布时间】:2016-06-14 18:34:13
【问题描述】:

我有一个依赖于字符串列表的组件:

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

使用 Castle Windsor,我试图从我的 app.config 文件的 AppSettings 部分提供这种依赖关系,如下所示:

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

Inline Dependencies 上的温莎文档说:

appSettings 和转换:配置文件中的值存储为文本,但代码中的依赖关系可能是其他类型(本例中为TimeSpan)。 Windsor 已为您服务,并且在大多数情况下会为您执行适当的转换。

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

【问题讨论】:

    标签: c# dependency-injection castle-windsor


    【解决方案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 中,然后手动拆分它们。

    这可能是更简单的方法,但假设您可以找出字符串的分隔符(可能并非总是如此)。将值添加到您的 App.config 文件中:

    <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 是扩展名(在我看来),我不知道或看到任何其他地方你会这样做。但是,鉴于上述步骤,我认为没有必要这样做。

    【讨论】:

    • 非常感谢您的详细回答 - 我现在选择了选项 2。
    • 实际上,我认为对我的第一个问题的“是,但是”的答案是“否”。虽然 Windsor 让我(开箱即用)将 TimeSpan 值放在 appSettings 中,但它不允许我对 List(或 string[])值做同样的事情。我想弄清楚 Windsor 在哪里将字符串值“反序列化”到 TimeSpan,看看是否可以将其扩展到 List.
    • convesions 子系统看起来是魔法发生的地方:github.com/castleproject/Windsor/blob/master/docs/subsystems.md,但我找不到太多关于它的文档。
    • 供将来参考:@mark-seemann 有一篇与此主题相关的博文:blog.ploeh.dk/2012/11/07/AppSettingsconventionforCastleWindsor
    • 好发现。看起来您可能可以创建一个 ISubDependencyResolver,就像在 Mark 的帖子中那样,以一种更“Windsory”的方式来做到这一点。
    猜你喜欢
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 2016-02-25
    • 2010-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多