2010-01-13 60 views
2

我一直在努力解決這個問題,雖然一些優雅的將是首選任何舊的黑客會在這一點上做的:)城堡溫莎 - 分期與生產的connectionString參數分量

我有一個存儲庫是註冊類似:

<castle> 
<properties> 
     <myConnStr>Data Source=COMPUTERNAME\SQL2008;Initial Catalog=MyDB;Persist Security Info=True;User ID=username;Password=password</myConnStr> 
</properties> 
<components> 
     <component id="MyRepository" service="DomainModel.Abstract.IMyRepository, DomainModel" type="DomainModel.Concrete.MyRepository, DomainModel" lifestyle="PerWebRequest"> 
      <parameters> 
       <connectionString>#{myConnStr}</connectionString> 
      </parameters> 
     </component> 
</components> 

我試圖建立我的配置文件,這樣就不必修改myConnStr財產部分的各種部署選項。這很好(甚至理想),如果我只能在配置第一次加載時建立connectionString一次,但在設置我的容器時我無法弄清楚如何設置此值。

如果我不使用castle windsor,我只需要定義多個連接字符串,如「connectionStringStaging」,「connectionStringProduction」,並根據我的環境(計算機名稱或URL)通過代碼選擇適當的連接字符串。我怎樣才能做到這樣的城堡溫莎物業?修改組件的「參數」而不是「屬性」也是可以接受的。

+0

問題添加到Windsor常見問題中:http://using.castleproject.org/display/IoC/FAQ – 2010-01-24 17:03:05

回答

2

我更喜歡一個簡單的解決方案,而不是推動框架爲你執行魔術。我會將連接字符串包裝到另一個類中,以提供與您的存儲庫的正確連接並將其添加到依賴關係樹中。

public interface IConnectionFactory 
{ 
    public string GetConnectionString(); 
} 

將此傳遞到您的'存儲庫'而不是字符串。

+0

完美。我早期的解決方法之一是可能讓我的存儲庫取得一個返回字符串的委託,並查看是否可以讓Windsor注入一個字符串。我無法讓它工作,但這基本上是一回事。 – 2010-01-13 17:27:52

+0

它當然可以工作,但是如果你對每個「動態」參數使用這種方法,你最終會得到很多可以很容易避免的接口和類。測試也變得更加困難,因爲您需要模擬IConnectionFactory而不是傳遞字符串。 – 2010-01-13 17:39:10

0

你不能這樣做......

<castle> 
<properties> 
     <dev>Data Source=COMPUTERNAME\SQL2008;Initial Catalog=MyDB;Persist Security Info=True;User ID=username;Password=password</dev> 
     <stage>Data Source=COMPUTERNAME\SQL2008;Initial Catalog=MyDB;Persist Security Info=True;User ID=username;Password=password</stage> 
     <production>Data Source=COMPUTERNAME\SQL2008;Initial Catalog=MyDB;Persist Security Info=True;User ID=username;Password=password</production> 
</properties> 
<components> 
     <component id="MyRepository" service="DomainModel.Abstract.IMyRepository, DomainModel" type="DomainModel.Concrete.MyRepository, DomainModel" lifestyle="PerWebRequest"> 
      <parameters> 
       <connectionString>#{dev|stage|production}</connectionString> 
      </parameters> 
     </component> 
</components> 

否則看看使用configSource屬性和儲存在3個獨立的配置文件的環境設置。 http://weblogs.asp.net/fmarguerie/archive/2007/04/26/using-configsource-to-split-configuration-files.aspx

配置選擇應該是代碼庫外部的顯式活動。

+0

「#{dev | stage | production}」 - > AFAIK這種語法不受Windsor支持... – 2010-01-13 02:16:48

+0

「配置選擇應該是代碼庫外部的顯式活動。」 - >我同意,但如果OP想要選擇基於計算機名稱或URL的連接,必須有代碼... – 2010-01-13 02:28:51

+0

我同意,但我還不喜歡任何支持此方法的解決方案。在每次發佈之前修改web.config是非常容易出錯的,自動web.config合併/更新(msbuild自定義,web部署項目等)的各種解決方案非常複雜。對於大型項目而言,這是行得通的,但在我的環境中,我們支持數百個應用程序,並且需要能夠從源代碼安全獲取解決方案,快速更改併發布的初級開發人員。希望VS2010中的'轉換'解決方案能夠解決問題。 – 2010-01-13 17:42:40

4
IWindsorContainer container = ... 
container.Register(Component.For<IMyRepository>().ImplementedBy<MyRepository>() 
    .LifeStyle.PerWebRequest 
    .Parameters(Parameter.ForKey("connectionString").Eq(GetConnectionStringFromEnviroment()))); 

其中GetConnectionStringFromEnviroment()會從你的配置的<connectionStrings>部分適當的連接或任何你想要的。

如果您需要這是在XML配置而不是代碼,你可以:

  • 編寫特定參數的ISubDependencyResolver
  • 使用defines and ifs(這可能是最簡單的解決方案,如果你已經使用XML配置)
+0

我最終選擇了其他解決方案之一,但實際上這正是我最初尋找的內容 - 謝謝! – 2010-01-13 17:24:46

0

免責聲明:這是我寫的

FWIW,這對你可能是矯枉過正,但我已經編寫了一個部署系統來處理這種情況(針對不同服務器的不同配置);它被稱爲dashy。它目前正在開發中(但是您可以下載的版本應該可以工作,達到合理的程度:P),因此我不建議將其用於即時實時使用;但隨時可以在開發/分期環境中給它一個破解,看看它是否有用。它不僅僅是你所需要的,但可能是有趣的:)