Доступ к значению ConfigurationManager.AppSettings из конфигурации Spring.NET xml

У меня есть требование, которое требует, чтобы я использовал Spring.net для получения строки подключения, которая хранится внутри app.config, а затем вставил полученную строку подключения в созданный объект.

Как я могу сделать это с помощью конфигурации Spring.net xml?

Например, вместо моих кодов это делается:

// Spring.net config:
<object name="myService" type="com.acme.MyService, com.acme">
    <constructor-arg type="System.String" value="myConnectionName"/>
</object>

// Web.config:
<connectionStrings>
    <add name="myConnectionName" connectionString="DB_connectionstring"/>
</connectionStrings>
// Codes:
public class MyService {
    public MyService(string connectionName) {
        var connectionString = ConfigurationManager.AppSettings[connectionName];
        // use connectionString to create a DB connection, etc
    }
}

Я хочу вот так:

 // Spring.net config:
<object name="myService" type="com.acme.MyService, com.acme">
    <constructor-arg type="System.String" ref="retrievedConnectionString"/>
</object>    
// How to make a call similar to "ConfigurationManager.AppSettings[connectionName]" and get the connection string from Web.config and put inside "retrievedConnectionString"?

// Web.config:
<connectionStrings>
    <add name="myConnectionName" connectionString="DB_connectionstring"/>
</connectionStrings>
// Codes:
public class MyService {
    public MyService(string connectionString) {
        // use connectionString to create a DB connection, etc
    }
}

Можно ли вообще вызвать ConfigurationManager.AppSettings[..] из конфигурации Spring.net xml?


person swirlobt    schedule 03.11.2011    source источник


Ответы (2)


Раньше для этого я использовал выражение, но с помощью этого вопроса и ответа bbaia , Я обнаружил, что лучший способ сделать это - использовать VariablePlaceholderConfigurer. Когда вы используете VariablePlaceholderConfigurer вместо моего "выражения-хака", вы не привязываете себя к конфигурации стиля appSettings / connectionStrings ваших переменных: вы можете переключиться на один из VariableSources, предоставленных spring.net, или даже реализовать свой собственный IVariableSource.

Spring.NET по умолчанию предоставляет VariablePlaceholderConfigurers для извлечения переменных из стандартных параметров .NET, таких как AppSettings, ConnectionStrings, UserSettings и ApplicationSettings. Это частично проиллюстрировано ответом bbaia, и вы найдете полный пример ниже.

"Expression hack": вызов ConfigurationManager из конфигурации xml

Итак, я не советую вам использовать это, но это хак, который я использовал в прошлом, применительно к вашей конфигурации:

<object object name="myService" type="com.acme.MyService, com.acme">
  <constructor-arg name="Connection" 
                   expression="T(System.Configuration.ConfigurationManager).ConnectionStrings['myConnectionName']" />
</object>

Вы можете использовать тот же подход для ConfigurationManager.AppSettings, например:

<object object name="myService" type="com.acme.MyService, com.acme">
  <constructor-arg name="AnotherConstructorArgument" 
                   expression="T(System.Configuration.ConfigurationManager).AppSettings['mySetting']" />
</object>

VariablePlaceholderConfigurer: ссылка на настройки .NET из конфигурации Spring.NET xml

Вы можете легко настроить VariablePlaceholderConfigurer для получения переменных из стандартных параметров .NET, таких как AppSettings, ConnectionStrings, UserSettings и ApplicationSettings. Например, рассмотрим эту конфигурацию xml:

<?xml version="1.0" encoding="utf-8"?>
<objects xmlns="http://www.springframework.net" >

  <object type="Spring.Objects.Factory.Config.VariablePlaceholderConfigurer, Spring.Core">
    <property name="VariableSources">
      <list>
        <object type="Spring.Objects.Factory.Config.ConnectionStringsVariableSource, Spring.Core" />
        <object type="Spring.Objects.Factory.Config.ConfigSectionVariableSource, Spring.Core">
          <!-- Sections to read, sepearated by comma (leave out spaces) -->
          <property name="SectionNames"
                    value="appSettings,applicationSettings/q7991262.Properties.Settings,userSettings/q7991262.Properties.Settings" />
        </object>
      </list>
    </property>
  </object>

  <!-- Note that you have to append '.connectionstring' to the key! -->
  <object id="usingConnectionStringsVariableSource" 
          type="q7991262.MyService, q7991262">
    <property name="Connection" 
              value="${myConnectionName.connectionString}" />
  </object>

  <object id="configSectionVariableSource" 
          type="q7991262.MyService, q7991262">
    <property name="Connection" 
              value="${myConnectionNameAppSettings}" />
  </object>

  <object id="userSettingsSection" 
          type="q7991262.MyService, q7991262">
    <property name="Connection" 
              value="${myConectionNameUserSetting}" />
  </object>

  <object id="applicationSetting" 
          type="q7991262.MyService, q7991262">
    <property name="Connection" 
              value="${myConectionNameApplicationSetting}" />
  </object>

</objects>

Он читает настройки из этого app.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
      <section name="q7991262.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
    </sectionGroup>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
      <section name="q7991262.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup>
  </configSections>

  <connectionStrings>
    <add name="myConnectionName" 
         connectionString="From connection string section."/>
  </connectionStrings>

  <appSettings>
    <add key="myConnectionNameAppSettings" 
         value="From app setting section." />
  </appSettings>

  <userSettings>
    <q7991262.Properties.Settings>
      <setting name="myConectionNameUserSetting" serializeAs="String">
        <value>My connection from user settings.</value>
      </setting>
    </q7991262.Properties.Settings>
  </userSettings>

  <applicationSettings>
    <q7991262.Properties.Settings>
      <setting name="myConectionNameApplicationSetting" serializeAs="String">
        <value>My connection from application settings.</value>
      </setting>
    </q7991262.Properties.Settings>
  </applicationSettings>

</configuration>

Эти конфигурации взяты из этого рабочего образца на github.

person Marijn    schedule 03.11.2011
comment
Я отмечаю это как ответ, потому что в нем приведены примеры извлечения значений как из appSettings, так и из connectionStrings, чего я и хочу. - person swirlobt; 10.11.2011

Другое решение - использовать VariablePlaceholderConfigurer: http://www.springframework.net/doc-latest/reference/html/objects.html#objects-variablesource.

Реализация ConnectionStringsVariableSource позволяет вам получить значение из раздела ConnectionString в вашем файле конфигурации.

<object type="Spring.Objects.Factory.Config.VariablePlaceholderConfigurer, Spring.Core">
  <property name="VariableSources">
    <list>
      <object type="Spring.Objects.Factory.Config.ConnectionStringsVariableSource, Spring.Core"/>
    </list>
  </property>
</object>

<object name="myService" type="com.acme.MyService, com.acme">
    <constructor-arg type="System.String" value="${myConnectionName.connectionString}"/>
</object>

Пример с форума Spring.NET: http://forum.springframework.net/showthread.php?3961

person bbaia    schedule 03.11.2011
comment
Собирался добавить и это, но в моем случае это не сработало, потому что я забыл добавить .connectionString к имени, которое требуется для ConnectionStringsVariableSource. Вы можете получить имя провайдера, используя value="${myConnectionName.providerName}". - person Marijn; 03.11.2011
comment
К сожалению, реализации IVariableSource не документированы. Вы должны копаться в коде, как и вы. - person bbaia; 04.11.2011