Castle Windsor服务覆盖XML配置

时间:2013-12-18 20:18:48

标签: castle-windsor xml-configuration

我使用xml配置在Castle Windsor中设置组件。我有这个配置:

  <component id="SurescriptsDatabase"

    service="System.Data.IDbConnection, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"
    type="System.Data.SqlClient.SqlConnection, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" lifestyle="transient">
    <parameters>
      <connectionString>REDACTED1</connectionString>
    </parameters>
  </component>
  <component id="Surescriptsv10Database"
    service="System.Data.IDbConnection, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"
    type="System.Data.SqlClient.SqlConnection, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" lifestyle="transient">
    <parameters>
      <connectionString>REDACTED2</connectionString>
    </parameters>
  </component>
  <component id="Surescriptsv10StagingDatabase"
    service="System.Data.IDbConnection, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"
    type="System.Data.SqlClient.SqlConnection, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" lifestyle="transient">
    <parameters>
      <connectionString>REDACTED3</connectionString>
    </parameters>
  </component>

  <component id="SurescriptsWatcher" 
             type="PatientFirst.Framework.Services.ScalarQueryWatcher, PatientFirst.Framework.Services">
    <parameters>
      <Database>${SurescriptsDatabase}</Database>
      <Frequency>0.00:01:00</Frequency>
      <CustomMessage>Surescripts v6 is not running</CustomMessage>
      <Query>select count(1) from [SureScripts_Production].[dbo].[ToSureScriptMessagesQueue] where requesttime &lt; dateadd(minute,-1,getdate()) and responsetime is null</Query>
      <MinResult>-1</MinResult>
      <MaxResult>0</MaxResult>
    </parameters>
  </component>
  <component id="Surescriptsv10Watcher" type="PatientFirst.Framework.Services.ScalarQueryWatcher, PatientFirst.Framework.Services">
    <parameters>
      <Database>${Surescriptsv10Database}</Database>
      <Frequency>0.00:01:00</Frequency>
      <CustomMessage>Surescripts v10 is not running</CustomMessage>
      <Query>select count(1) from [SureScripts_v10_Production].[dbo].[ToSureScriptMessagesQueue] where requesttime &lt; dateadd(minute,-1,getdate()) and responsetime is null</Query>
      <MinResult>-1</MinResult>
      <MaxResult>0</MaxResult>
    </parameters>
  </component>
  <component id="Surescriptsv10StagingWatcher" type="PatientFirst.Framework.Services.ScalarQueryWatcher, PatientFirst.Framework.Services">
    <parameters>
      <Database>${Surescriptsv10StagingDatabase}</Database>
      <Frequency>0.00:01:00</Frequency>
      <CustomMessage>Surescripts v10 Staging is not running</CustomMessage>
      <Query>select count(1) from [SureScripts_v10_Staging].[dbo].[ToSureScriptMessagesQueue] where requesttime &lt; dateadd(minute,-1,getdate()) and responsetime is null</Query>
      <MinResult>-1</MinResult>
      <MaxResult>0</MaxResult>
    </parameters>
  </component>

在我的ScalarQueryWatcher构造函数中,我总是得到相同的数据库连接。如果我删除了SQLConections的组件定义的service =部分,那么Windsor抱怨:

  

Castle.MicroKernel.Handlers.HandlerException:无法创建组件&gt;&#39; serviceBootstrapper&#39;因为它有依赖性来满足。

     

&#39; SurescriptsWatcher&#39;正在等待以下依赖项:    - 服务&#39; System.Data.IDbConnection&#39;没有注册。    - 组件&#39; Surescriptsv10Watcher&#39; (通过覆盖)已注册,但也在等待依赖。

     

&#39; Surescriptsv10Watcher&#39;正在等待以下依赖项:    - 服务&#39; System.Data.IDbConnection&#39;没有注册。    - 组件&#39; Surescriptsv10StagingWatcher&#39; (通过覆盖)已注册,但也在等待依赖。

     

&#39; Surescriptsv10StagingWatcher&#39;正在等待以下   依赖关系:    - 服务&#39; System.Data.IDbConnection&#39;没有注册。

我在这里做错了什么?通过阅读文档,我认为使用组件的id指定<Database>${SurescriptsDatabase}</Database>会给我那个特定的组件。


UPDATE 我想早点做到这一点,在这里你可以找到后来的后代。问题不在于XML配置,而是在源代码中:

Public Class ScalarQueryWatcher

Public Sub New(ByVal Query As String,
 ByVal Connection As IDbConnection,
 ByVal Frequency As TimeSpan,
 ByVal MinResult As Integer, ByVal MaxResult As Integer)
    _database = Connection
    'this should get the table we're querying from
    If String.IsNullOrEmpty(Query) Then Throw New ApplicationException("Query cannot be null")
    _queryName = Query.Substring(Query.IndexOf("FROM", StringComparison.CurrentCultureIgnoreCase) + 5)
    If _queryName.Contains(" ") Then _queryName = _queryName.Substring(0, _queryName.IndexOf(" "))
    _query = Query
    _frequency = Frequency
    _minResult = MinResult
    _maxResult = MaxResult
    _range = _maxResult - _minResult
End Sub

1 个答案:

答案 0 :(得分:1)

请注意,构造函数参数名称是Connection,而不是我在xml配置中引用它的数据库。这就是它在指定服务类型时“工作”的原因,它会抓取与IDbConnection匹配的任何内容。当我开始使用正确的构造函数参数名称时,我得到了由id指定的数据库。

Public Sub New(ByVal Query As String,
 ByVal Connection As IDbConnection,         'Note the name here is Connection
 ByVal Frequency As TimeSpan,
 ByVal MinResult As Integer, ByVal MaxResult As Integer)
    _database = Connection
    'this should get the table we're querying from
    If String.IsNullOrEmpty(Query) Then Throw New ApplicationException("Query cannot be null")
    _queryName = Query.Substring(Query.IndexOf("FROM", StringComparison.CurrentCultureIgnoreCase) + 5)
    If _queryName.Contains(" ") Then _queryName = _queryName.Substring(0, _queryName.IndexOf(" "))
    _query = Query
    _frequency = Frequency
    _minResult = MinResult
    _maxResult = MaxResult
    _range = _maxResult - _minResult
End Sub

  <component id="SurescriptsWatcher" 
             type="PatientFirst.Framework.Services.ScalarQueryWatcher, PatientFirst.Framework.Services">
    <parameters>
      <Database>${SurescriptsDatabase}</Database>  <!--note the parameter here is database, which does not match the constructor parameter -->
      <Frequency>0.00:01:00</Frequency>
      <CustomMessage>Surescripts v6 is not running</CustomMessage>
      <Query>select count(1) from [SureScripts_Production].[dbo].[ToSureScriptMessagesQueue] where requesttime &lt; dateadd(minute,-1,getdate()) and responsetime is null</Query>
      <MinResult>-1</MinResult>
      <MaxResult>0</MaxResult>
    </parameters>
  </component>