如何使用静态常量变量作为Spring IOC中列表的输入

时间:2011-08-03 19:28:36

标签: ioc-container spring.net

这是我需要做的......

我有一份所需的依赖服务列表。为了举例,我们称之为ServiceA,ServiceB和ServiceC。我需要能够在我的spring配置文件中定义这些服务的任何排列。所以例如我可以

<constructor-arg name="requiredServices">
  <list element-type="string">
    <value>ServiceA</value>
    <value>ServiceB</value>
  </list>
</constructor-arg>

这表明我需要服务A和B.我的问题是,我在Spring文件中使用本地字符串来引用ServiceA和ServiceB,而我宁愿为ServiceA和ServiceB使用系统范围的常量名称。所以我想我想看到的是

<constructor-arg name="requiredServices">
  <list element-type="string">
    <value>MyStringConstantsFile.ServiceA</value>
    <value>MyStringConstantsFile.ServiceB</value>
  </list>
</constructor-arg>

然后,如果我们重命名ServiceA,spring.config文件仍然可以正常运行。

3 个答案:

答案 0 :(得分:4)

使用Spring expression,您的配置可能如下所示:

<object id="myObject" type="q6932134.ServiceClient, q6932134">
  <constructor-arg name="requiredServices">
    <list element-type="string">
      <expression value="MyConstants.ServiceA" />
      <expression value="MyConstants.ServiceB" />
    </list>
  </constructor-arg>
</object> 

这非常接近你问题中所需的配置: - )

要使其正常工作,您必须使用spring注册MyConstants类型;将以下代码放在主程序中的某个位置:

TypeRegistry.RegisterType("MyConstants", typeof(MyConstants));

以下替代配置允许您使用对象引用,与您自己的答案非常相似。这使得配置更加冗长,但是具有以下优点:配置文件对于在代码中重命名常量变得不那么敏感:

  <object id="svca" type="string">
    <constructor-arg expression="MyConstants.ServiceA" />
  </object>
  <object id="svcb" type="string">
    <constructor-arg expression="MyConstants.ServiceB" />
  </object>

  <object id="myObject" type="q6932134.ServiceClient, q6932134">
    <constructor-arg name="requiredServices">
      <list element-type="string">
        <ref object="svca" />
        <ref object="svcb" />
      </list>
    </constructor-arg>
  </object> 

如果您不想以编程方式注册MyConstants,可以按如下方式更改表达式:

<constructor-arg expression="T(MyNamespace.MyConstants).ServiceA" />

答案 1 :(得分:1)

这需要一点点敲击,但我得到了我需要的东西。您需要分两步解决问题。

首先,为您要使用的每个常量在spring配置文件中添加一个条目。我看起来像这样

<object id="serverAName"
        type="Spring.Objects.Factory.Config.FieldRetrievingFactoryObject, Spring.Core">
  <property name="TargetType" value="CoreNamespace.ConstantsClass, CoreLibrary"/>
  <property name="TargetField" value="ServerAName"/>
</object>

因此,在名为CoreLibrary的程序集中,我有一个名为ConstantsClass的类,它存在于名称空间CoreNamespace中。

然后,如果我想将此常量用作列表的输入,我只需将以下行添加到spring配置文件中

<property name="RequiredComponents">
  <list element-type="string">
    <ref object="serverAName"/>
  </list>
</property>

答案 2 :(得分:0)

我不知道spring是否支持开箱即用,但您可以在正在构建的对象的代码中读取带有反射的那些。

或者创建一个类似帮助器的解析器,而不是分配字符串列表,您可以分配这些引用的列表,尽管xml定义将比现在更详细。

HTH