2

我正在使用 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:无法创建组件 >'serviceBootstrapper',因为它需要满足依赖项。

“SurescriptsWatcher”正在等待以下依赖项: - 未注册的服务“System.Data.IDbConnection”。- 已注册但也在等待依赖项的组件“Surescriptsv10Watcher”(通过覆盖)。

“Surescriptsv10Watcher”正在等待以下依赖项: - 未注册的服务“System.Data.IDbConnection”。- 已注册但也在等待依赖项的组件“Surescriptsv10StagingWatcher”(通过覆盖)。

“Surescriptsv10StagingWatcher”正在等待以下依赖项: - 未注册的服务“System.Data.IDbConnection”。

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


更新意味着更早地执行此操作,在这里为以后的后代做准备。问题不在于 XML 配置,而在于源代码:

公共类 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
4

1 回答 1

1

请注意,构造函数参数名称是 Connection,而不是我在 xml 配置中引用的 Database。这就是在指定服务类型时它“工作”的原因,它会抓取与 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>
于 2014-02-12T15:24:54.730 回答