2012-06-07 72 views
4

我們正在開發一個系統,其中客戶端應用程序是一個使用Web服務與服務器通信的.NET客戶端。我們需要能夠使用不同的配置選項部署客戶端,例如IP地址等 到目前爲止,我們已經通過基本註釋/取消註釋中的app.config不同的配置,像這樣管理:在app.config中管理多個客戶端端點配置(IP地址等)的最佳方法

<!--<client> 
    <endpoint address="https://localhost/services/service1" 
     binding="customBinding" bindingConfiguration="ServiceSoapBinding" 
     contract="ServiceReference.Service1" name="ServiceImplPort" /> 
    <endpoint address="https://localhost/services/service2" 
     binding="customBinding" bindingConfiguration="ServiceSoapBinding" 
     contract="ServiceReference.Service2" name="ServiceImplPort" /> 
    ... 
    .. 
</client>--> 
<client> 
    <endpoint address="https://prod.example.com/services/service1" 
     binding="customBinding" bindingConfiguration="ServiceSoapBinding" 
     contract="ServiceReference.Service1" name="ServiceImplPort" /> 
    <endpoint address="https://prod.example.com/services/service2" 
     binding="customBinding" bindingConfiguration="ServiceSoapBinding" 
     contract="ServiceReference.Service2" name="ServiceImplPort" /> 
    ... 
    .. 
</client> 

但似乎很明顯,這不是解決問題的最好解決方案,隨着配置方案數量的增長,變得有點難以管理。任何建議如何改善這是最受歡迎的。

問候,奧拉

+0

沒有爲「有條件的ClickOnce部署爲構建配置」,可能會感興趣的MSDN開發中心的相關討論。 http://social.msdn.microsoft.com/Forums/en/winformssetup/thread/71933eaf-4a21-4923-bccd-19dd851dc7c3 –

回答

2

幸運的是,這個問題有一個很好的解決方案。下載並安裝MSBuild.Community.Tasks

然後檢查例如使用

http://chris.widdowson.id.au/?p=781

http://grahamrhay.wordpress.com/2012/03/16/multiple-config-transforms-at-build-time/

警告下列職位需要超過5分鐘設置,你將被編輯.csproj文件

此解決方案確實工作得很好,回來的任何問題

+0

這個解決方案很好地工作到一個點(在我們的例子中)。這個想法基本上是在構建時使用MSBuild.Community.Tasks支持的「任務」將正確的配置注入到app.config中。我們發現,如果您使用Click-Once部署來發布應用程序,則發佈時任務不會運行。即當您在Visual Studio中使用正常的構建過程時,它可以完美地工作,但只要我們發佈(單擊一次部署)應用程序,app.config就不會更新,因此根本不會包含任何終端配置。 –

+0

@OlaTheander我很驚訝。你是構建過程的一部分嗎?在我們的程序中,我們使用一個'UsingTask TaskName ='TransformXml'',後面跟着一個''以便在每次編譯到中間輸出路徑後生成所有的各種配置。完成此任務後,將配置文件複製到適當的位置。 – wal

+0

我們使用了但我更改爲AfterCompile,但它沒有幫助。我們使用發佈選項卡上的發佈按鈕(VS 2010)從VS內部發布。發佈後,如果我打開由目標服務器上一次部署生成的****。exe.config.deploy文件(通常位於名爲類似APP-NAME_1_0_0_0的子文件夾中),端點的配置部分爲仍然 <! - 爲每個env配置 - 請參閱轉換文件 - >即配置文件似乎按原樣發佈沒有AfterCompile任務更新。這確實很奇特。 –

1

我們使用MSI軟件包部署我們的應用程序(使用維克斯建)已經很開心了,並且調用我們包裝我們的產品XMLPreprocess可執行自定義操作。它基本上使用XPath和我們用Excel維護的一些XML文件來處理重新配置app/web.config文件。我們已經使用了它一段時間了,並且沒有任何產品問題。

這裏有一個鏈接:http://xmlpreprocess.codeplex.com/

如果你要詳細說明你的部署策略給你的一些情況具體答案這將是有益的。

編輯:我也許應該補充這是一個內部的產品而已,你不會想如果你不在外部給予的MSI使用這種方法。

1

我們曾嘗試沃爾瑪的做法幾乎解決了這個問題,但我們遇到了與點擊一次部署,請參閱我的沃爾瑪的答覆意見的問題。

我們目前正在使用的解決方案是在此張貼提示條件編譯:

http://www.codeproject.com/Articles/451734/Visual-Studio-Use-Conditional-Compilation-to-Contr

的優點是,除了有一次點擊,完美的工作,就是你不必調整VS項目文件或使用任何第三方組件。缺點是如果您想添加/更改端點,則需要更新源代碼。

我們所做的是將新的.setttings文件添加到項目中。這並不是強制性的,但我們認爲將終端配置保存在單獨的設置文件中是個好主意,因爲這個文件必須稍微調整。它的調整,以使用條件編譯基於對編譯啓用配置,使正確的端點:

public ServiceSettings() { 
     // // To add event handlers for saving and changing settings, uncomment the lines below: 
     // 
     // this.SettingChanging += this.SettingChangingEventHandler; 
     // 
     // this.SettingsSaving += this.SettingsSavingEventHandler; 
     // 

     // Each method corrsponds to a build version. We call all four methods, because 
     // the conditional compilation will only compile the one indicated: 
     this.SetLocalApplicationSettings(); 
     this.SetAS12ApplicationSettings(); 
    } 

    [Conditional("LOCAL")] 
    private void SetLocalApplicationSettings() 
    { 
     this["LoginAddress"] = "https://localhost/services/loginservice"; 
     this["SettingsAddress"] = "https://localhost/services/settingsservice"; 
    } 

    [Conditional("EXAMPLE")] 
    private void SetAS12ApplicationSettings() 
    { 
     this["LoginAddress"] = "https://example.com/services/loginservice"; 
     this["SettingsAddress"] = "https://example.com/services/settingsservice"; 
    } 

在VS,我們創建一個配置每個端點和定義生成選項卡上的適當條件編譯符號,即本地或例。

我們還更新使用VS生成的使用在設置中定義的端點的WS客戶端類的代碼文件:

var client = new SettingsServiceClient("SettingsServiceImplPort", 
    ServiceSettings.Default.SettingsAddress); 

在App.config我們只是保留了默認配置(本地主機)和綁定配置保持VS幸福:

<system.serviceModel> 
    <bindings> 
    <customBinding> 
     <binding name="SettingsServiceImplServiceSoapBinding"> 
     <textMessageEncoding messageVersion="Soap12" /> 
     <httpsTransport /> 
     </binding> 
     <binding name="LoginServiceImplServiceSoapBinding"> 
     <textMessageEncoding messageVersion="Soap12" /> 
     <httpsTransport /> 
     </binding> 
    </customBinding> 
    </bindings> 
    <client> 
    <endpoint address="https://localhost/services/settingsservice" 
     binding="customBinding" bindingConfiguration="SettingsServiceImplServiceSoapBinding" 
     contract="SettingsServiceReference.SettingsService" name="SettingsServiceImplPort" /> 
    <endpoint address="https://localhost/services/loginservice" 
     binding="customBinding" bindingConfiguration="LoginServiceImplServiceSoapBinding" 
     contract="LoginServiceReference.LoginService" name="LoginServiceImplPort" /> 
    </client> 
</system.serviceModel> 
<applicationSettings> 
    <ConfigurationTest.ServiceSettings> 
     <setting name="SettingsAddress" serializeAs="String"> 
      <value>https://localhost/services/settingsservice</value> 
     </setting> 
     <setting name="LoginAddress" serializeAs="String"> 
      <value>https://localhost/services/loginservice</value> 
     </setting> 
    </ConfigurationTest.ServiceSettings> 
</applicationSettings>