Birkaç derleme yapılandırması için farklı app.config nasıl seçilir


115

Ben var dll tip projesi MSTest entegrasyon testleri içerir. Makinemde testler geçer ve aynısının bir CI sunucusunda olmasını istiyorum (TeamCity kullanıyorum). Ancak app.config dosyasında bazı ayarları değiştirmem gerektiğinden testler başarısız oluyor. Bu nedenle, CI sunucusu ayarlarını tutacak ayrı bir ikinci app.config dosyasına sahip olmayı düşünüyordum.

Bu yüzden sahip olmak isterdim

/ Sln
 / Proj
  app.config (Bunun VS tarafından gerekli olduğunu düşünüyorum)
  app.Release.config (Bu bağımsız, bağımsız bir yapılandırma dosyasıdır)

Bu nedenle, CI üzerinde derleme yapılandırmasında Yayın yapılandırmasını seçersem, app.config yerine app.Release.config dosyasını kullanmak isterim

Sorun
Bu, basit .dll türü projeler için kolay görünmüyor. Web projeleri için web yapılandırma dönüşümleri yapabilirim. Dll türü bir proje için bu dönüşümlerin nasıl yapılacağına dair bir hack buldum, ancak büyük bir hack hayranı değilim.

Soru
.NET projeleri için derleme yapılandırmasına (Debug, Release, ... gibi) bağlı olarak app.config dosyalarını değiştirmek için standart bir yaklaşım nedir?

Yanıtlar:


154

SlowCheetah eklentisini kullanın . SlowCheetah'ın nasıl kullanılacağına dair daha fazla seçenek ve ayrıntı için okumaya devam edin.

Daha önce fark ettiğiniz gibi, bir Kitaplık türü (.dll) projesi için farklı yapılandırma dosyalarını kullanmanın varsayılan ve kolay bir yolu yoktur . Bunun nedeni, şu anki düşüncenin "gerek yok" olmasıdır! Çerçeve geliştiricileri, yürütülebilir dosya için yapılandırmaya ihtiyacınız olduğunu varsayar: bir konsol, masaüstü, web, mobil uygulama veya başka bir şey olabilir. Bir dll için yapılandırma sağlamaya başlarsanız , yapılandırma cehennemi diyebileceğim bir şeyle karşılaşabilirsiniz . Artık (kolayca) neden bunun ve bu değişkenlerin görünüşte hiçbir yerden gelen bu kadar tuhaf değerlere sahip olduğunu anlayamayabilirsiniz.

"Bekleyin", diyebilirsiniz, "ama buna entegrasyon / birim testim için ihtiyacım var ve bu bir kitaplık!". Ve bu doğru ve yapabileceğiniz şey bu (yalnızca birini seçin, karıştırmayın):

1. SlowCheetah - mevcut yapılandırma dosyasını dönüştürür

Sizin için tüm düşük seviyeli XML dürtmeyi (veya dönüştürmeyi) yapan bir Visual Studio eklentisi olan SlowCheetah'ı yükleyebilirsiniz . İşleyiş şekli kısaca:

  • SlowCheetah'ı yükleyin ve Visual Studio'yu yeniden başlatın (Visual Studio> Araçlar> Uzantılar ve Güncellemeler ...> Çevrimiçi> Visual Studio Galerisi> "Yavaş Çita" için arama yapın)
  • Çözüm yapılandırmalarınızı tanımlayın ( Hata Ayıklama ve Yayın varsayılan olarak vardır), daha fazlasını ekleyebilirsiniz ( Çözüm Gezgini > Yapılandırma Yöneticisi ... > Etkin Çözüm Yapılandırması > Yeni ...
  • Gerekirse bir yapılandırma dosyası ekleyin
  • Yapılandırma dosyasına sağ tıklayın> Dönüşüm Ekle
    • Bu, yapılandırmanız başına bir tane olmak üzere Dönüşüm dosyaları oluşturacaktır
    • Dönüştürme dosyaları enjektör / mutatör olarak çalışır, orijinal yapılandırma dosyasında gerekli XML kodunu bulur ve yeni satırlar enjekte eder veya gerekli değeri değiştirir, ne yapmasını söylerseniz yapın

2. .proj dosyasıyla oynayın - tamamen yeni bir yapılandırma dosyasını kopyalayıp yeniden adlandırır

Aslen buradan alınmıştır . Visual Studio .proj dosyasına ekleyebileceğiniz özel bir MSBuild görevidir . Aşağıdaki kodu kopyalayıp proje dosyasına yapıştırın

<Target Name="AfterBuild">
    <Delete Files="$(TargetDir)$(TargetFileName).config" />
    <Copy SourceFiles="$(ProjectDir)\Config\App.$(Configuration).config"
          DestinationFiles="$(TargetDir)$(TargetFileName).config" />
</Target>

Şimdi projede adı verilen bir klasör oluşturun Configve buraya yeni dosyalar ekleyin: App.Debug.config , App.Release.config vb. Şimdi, yapılandırmanıza bağlı olarak, Visual Studio bir Configklasörden yapılandırma dosyasını seçecek ve çıktı dizinine kopyalayıp yeniden adlandıracaktır. Dolayısıyla, PatternPA.Test.Integration projeniz ve bir Debug yapılandırması seçtiyseniz, derlemeden sonra çıktı klasöründe, buradan kopyalanan Config\App.Debug.configve daha sonra yeniden adlandırılan bir PatternPA.Test.Integration.dll.config dosyası bulacaksınız .

Bunlar, yapılandırma dosyalarında bırakabileceğiniz bazı notlar

<?xml version="1.0" encoding="utf-8"?>
<configuration>

    <!-- This file is copied and renamed by the 'AfterBuild' MSBuild task -->

    <!-- Depending on the configuration the content of projectName.dll.config 
        is fully substituted by the correspondent to build configuration file 
        from the 'Config' directory. -->

</configuration>

Visual Studio'da bunun gibi bir şeye sahip olabilirsiniz

Proje yapısı

3. Komut dosyası dosyalarını Visual Studio dışında kullanın

Her derleme aracı ( NAnt , MSBuild gibi ), yapılandırmaya bağlı olarak yapılandırma dosyasını dönüştürmek için yetenekler sağlayacaktır. Çözümünüzü, ürünü piyasaya sürmek için neyi ve nasıl hazırlayacağınız konusunda daha fazla kontrole sahip olmanız gereken bir yapı makinesinde oluşturuyorsanız bu yararlıdır.

Örneğin, herhangi bir yapılandırma dosyasını dönüştürmek için web yayımlama dll'sinin görevini kullanabilirsiniz.

<UsingTask AssemblyFile="..\tools\build\Microsoft.Web.Publishing.Tasks.dll"
    TaskName="TransformXml"/>

<PropertyGroup>
    <!-- Path to input config file -->  
    <TransformInputFile>path to app.config</TransformInputFile>
    <!-- Path to the transformation file -->    
    <TransformFile>path to app.$(Configuration).config</TransformFile>
    <!-- Path to outptu web config file --> 
    <TransformOutputFile>path to output project.dll.config</TransformOutputFile>
</PropertyGroup>

<Target Name="transform">
    <TransformXml Source="$(TransformInputFile)"
                  Transform="$(TransformFile)"
                  Destination="$(TransformOutputFile)" />
</Target>

İkinci çözümünüz iyi çalışıyor, ancak web projeleri yayınlamak için değil. Bir ASP.NET projesi yayınladıktan sonra, orijinal web.config yayınlanır.
Massood Khaari

3
@MassoodKhaari, bu görevin yayınlama hedefi için çağrıldığından emin olmanız gerekir. Bir proje yayınladığınızda, varsayılan AfterBuildhedef olarak çağrılmayan ayrı bir yapı hedefi çağrılır . Tipik derleme sırasında AfterBuildhedef varsayılan olarak çağrılır.
Yayın

1
İkinci yönteminizi kullandınız (tür). Proje özelliklerine gitti ve düzenlenmiş BeforeBuild kopyalamak App.<Target>.configüzerinde App.configde proje dir , değil Çıktı dir.
SparK

@oleksii Haklısın. Ancak web yayınlama sürecimin kullandığı hedefi hala bulamadım (Visual Studio 2013'te).
Massood Khaari

1
İkinci yöntemi kullanıyorum, ancak dosyanın silinmeden önce gerçekten var olduğundan emin olmak için AfterBuild hedefine bir koşul eklemem gerekiyor. Temelde yalnızca varsayılan App.config dosyasını kullanan bir Debug derleme yapılandırmam var, ancak uygulama adımının başarısız olacağı anlamına gelen App.Debug.config yoktu. Sadece eklendi Condition="Exists('$(ProjectDir)App.$(Configuration).config')".
Siewers

23

Aşağıdaki yaklaşımı deneyebilirsiniz:

  1. Solution Explorer'da projeye sağ tıklayın ve Unload Project'i seçin .
  2. Proje kaldırılacak. Projeye tekrar sağ tıklayın ve < Projenizin Adını> .csproj Düzenle'yi seçin .
  3. Artık proje dosyasını Visual Studio içinde düzenleyebilirsiniz.
  4. * .Csproj dosyasında uygulama yapılandırma dosyanızın bulunduğu yeri bulun. Şöyle görünecek:
    <ItemGroup>
        <Yok Include = "App.config" />
    </ ItemGroup>
  1. Bu satırları aşağıdaki ile değiştirin:
    <ItemGroup Koşul = "'$ (Yapılandırma)' == 'Hata Ayıklama'">
        <Yok Include = "App.Debug.config" />
    </ ItemGroup>

    <ItemGroup Koşul = "'$ (Yapılandırma)' == 'Serbest Bırak'">
        <Yok Include = "App.Release.config" />
    </ ItemGroup>

app.configDosyalara bu yaklaşımı denemedim , ancak Visual Studio projelerinin diğer öğeleriyle iyi çalıştı. Derleme sürecini neredeyse istediğiniz şekilde özelleştirebilirsiniz. Her neyse, sonucu bana bildirin.


Cevap için Tnx, ancak bu app.config ile çalışmıyor. VS app.configderlemesi veya Teamcity VS sln derleme çalıştırıcısı kullanırsam, VS bir zorunlu gerektirir ve Release yapılandırmasını uygulamıyor.
oleksii

2
Nasıl yapılacağı burada açıklanmaktadır: app.debug.config app.release.config'i etkinleştirin
Gabrielizalo

1
Bu yanıtın neden bu kadar çok oyu var? Denedim ve işe yaramıyor. Aslında hem hata ayıklama hem de yayınlama modunda App.config dosyası yoktur ve bu nedenle çıktı klasöründe karşılık gelen dosya yoktur. App.Debug.config ve App.Release.config dosyalarının Visual Studio için herhangi bir anlamı yoktur.
MarkusParker

Çalışmıyor: .csproj açılamıyor, hata mesajı "Hedef öğeler dışındaki öğelerde şunlar bulunmalıdır: Dahil Et, Güncelle veya Kaldır"
Elo

12

Sen düşünmelisiniz ConfigGen . Bu amaçla geliştirilmiştir. Bir şablon dosyası ve bir ayarlar dosyasına dayalı olarak her dağıtım makinesi için bir yapılandırma dosyası oluşturur. Bunun sorunuzu tam olarak yanıtlamadığını biliyorum, ancak sorununuza iyi yanıt verebilir.

Dolayısıyla, Hata Ayıklama, Yayınlama vb. Yerine Test, UAT, Üretim vb. Olabilir. Ayrıca her geliştirici makinesi için farklı ayarlara sahip olabilirsiniz, böylece geliştirici makinenize özel bir yapılandırma oluşturabilir ve başka birinin dağıtımını etkilemeden değiştirebilirsiniz. .

Bir kullanım örneği olabilir ...

<Target Name="BeforeBuild">
    <Exec Command="C:\Tools\cfg -s $(ProjectDir)App.Config.Settings.xls -t       
        $(ProjectDir)App.config.template.xml -o $(SolutionDir)ConfigGen" />

    <Exec Command="C:\Tools\cfg -s $(ProjectDir)App.Config.Settings.xls -t
        $(ProjectDir)App.config.template.xml -l -n $(ProjectDir)App.config" />
</Target>

Bunu .csproj dosyanıza yerleştirirseniz ve aşağıdaki dosyalara sahip olursanız ...

$(ProjectDir)App.Config.Settings.xls

MachineName        ConfigFilePath   SQLServer        

default             App.config      DEVSQL005
Test                App.config      TESTSQL005
UAT                 App.config      UATSQL005
Production          App.config      PRODSQL005
YourLocalMachine    App.config      ./SQLEXPRESS


$(ProjectDir)App.config.template.xml 

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
   <configuration>
   <appSettings>
       <add key="ConnectionString" value="Data Source=[%SQLServer%]; 
           Database=DatabaseName; Trusted_Connection=True"/>
   </appSettings>
</configuration>

... o zaman sonuç bu olacak ...

İlk komuttan, xls dosyasında belirtilen her ortam için oluşturulan ve $ (SolutionDir) ConfigGen çıktı dizinine yerleştirilen bir yapılandırma dosyası

.../solutiondir/ConfigGen/Production/App.config

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
   <configuration>
   <appSettings>
       <add key="ConnectionString" value="Data Source=PRODSQL005; 
           Database=DatabaseName; Trusted_Connection=True"/>
   </appSettings>
</configuration>

İkinci komuttan, dev makinenizde kullanılan yerel App.config, yerel (-l) anahtarı ve dosya adı (-n) anahtarı tarafından belirtilen oluşturulan yapılandırmayla değiştirilecektir.


2
Cevap için Tnx, bu fena değil. Ancak bazı dezavantajları vardır, yalnızca 75 indirme gösterir (bu nedenle olgun değildir) ve yalnızca .xls veya .xlsx ile çalışır. Basit işlemler için başka bir özel belge biçimine gerçekten güvenmek istemiyorum. Daha standart bir yaklaşım arıyordum ...
oleksii

2
Adil nokta, CodePlex'te 194 indirme yazmasına rağmen, xls bir elektronik tablodur, neredeyse özel bir formattır ve bunu kullanım için onaylayan üç Büyük Yatırım Bankası biliyorum, bu yüzden onlar için yeterince iyiyse ... Ayrıca, bir şu anda talep edilen özelliklerden biri, ayarlar için xml kullanmaktır. Neredeyse hazır, ancak yine de elektronik tablo yaklaşımını tercih ediyorum. Her ortam için her ayarı tablo halinde görmek çok daha kolay
Daniel Dyson

Şimdi, sadece xml değil, düz metin dosyaları oluşturmak için kullanılabilecek bir configGen sürümünü test etmenin son aşamalarındayız. Javascript vb ortama özgü css, sql, üretmek istiyorsak, configGen sitesinde göz kulak
Daniel Dyson

Çözüm için teşekkürler Daniel, tam olarak aradığım şey buydu. Bir deneyeceğim.
Bhupinder Singh

10

Romeo ile aynı yaklaşımı kullanarak, onu Visual Studio 2010'a uyarladım:

 <None Condition=" '$(Configuration)' == 'Debug' " Include="appDebug\App.config" />

 <None Condition=" '$(Configuration)' == 'Release' " Include="appRelease\App.config" />

Burada her iki App.config dosyasını farklı dizinlerde tutmanız gerekir (appDebug ve appRelease). Test ettim ve iyi çalışıyor!


3

Yapılandırma dosyalarının işlenmesi için XmlPreprocess aracını kullanıyorum . Birden çok ortam için bir eşleme dosyası (veya sizin durumunuzda birden çok oluşturma hedefi) kullanıyor. Eşleme dosyasını Excel ile düzenleyebilirsiniz. Kullanımı çok kolaydır.


3

VisualStudio Galerisi'nden SlowCheetah ve FastKoala, bu soruna yardımcı olan çok iyi araçlar gibi görünüyor.

Bununla birlikte, eklentilerden kaçınmak veya derleme / entegrasyon süreçlerinizde daha kapsamlı bir şekilde uyguladıkları ilkeleri kullanmak istiyorsanız, bunu msbuild * proj dosyalarınıza eklemek kısa bir düzeltmedir.

Not: Bu, az çok @ oleksii'nin cevabının 2 numaralı yeniden işidir.

Bu, .exe ve .dll projeleri için çalışır:

  <Target Name="TransformOnBuild" BeforeTargets="PrepareForBuild">
    <TransformXml Source="App_Config\app.Base.config" Transform="App_Config\app.$(Configuration).config" Destination="app.config" />
  </Target>

Bu, web projeleri için çalışır:

  <Target Name="TransformOnBuild" BeforeTargets="PrepareForBuild">
    <TransformXml Source="App_Config\Web.Base.config" Transform="App_Config\Web.$(Configuration).config" Destination="Web.config" />
  </Target>

Bu adımın, derleme düzgün başlamadan önce gerçekleştiğini unutmayın. Yapılandırma dosyasının dönüşümü proje klasöründe gerçekleşir. Böylece, dönüştürülen web.config, hata ayıklama sırasında kullanılabilir (SlowCheetah'ın bir dezavantajı).

App_Config klasörünü oluşturursanız (veya onu ne şekilde adlandırmayı seçerseniz seçin), çeşitli ara yapılandırma dosyalarının Build Action = None ve Copy to Output Directory = Do not copy olmalıdır.

Bu, her iki seçeneği de tek bir blokta birleştirir. Uygun olan, koşullara göre yürütülür. TransformXml görevi ilk olarak tanımlanır:

<Project>
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="TransformOnBuild" BeforeTargets="PrepareForBuild">
    <TransformXml Condition="Exists('App_Config\app.Base.config')" Source="App_Config\app.Base.config" Transform="App_Config\app.$(Configuration).config" Destination="app.config" />
    <TransformXml Condition="Exists('App_Config\Web.Base.config')" Source="App_Config\Web.Base.config" Transform="App_Config\Web.$(Configuration).config" Destination="Web.config" />
</Target>


Bunu Visual Studio 2017'de denedim ve çalışmıyor. Ateş etmek. Gerçekten işe yarayacağını umuyordum çünkü uygulaması en kolay gibi görünüyor.
Greg Burghardt

TransformXml görevi örneklerde tanımlanmamıştır. Bir girdi ekliyorum. Bunu, çözümünüzdeki tüm başlatma projelerinize dahil edilen bir mycustom.targets dosyasında tanımlayabilirsiniz.
Eniola

@GregBurghardt, şimdi denemek ister misin?
Eniola

Denemek için onu verebilirim. Visual Studio için Config Transform eklentisini kurdum ve bu gerçekten iyi çalıştı. Aslında eklentinin temelde cevabınızı yapıp yapmadığını merak ediyorum.
Greg Burghardt

Tamam, nasıl gittiğini bana bildirin.
Eniola

1

XDT (web.config) dönüşüm motorunun size yardımcı olup olamayacağını görün. Şu anda yalnızca web projeleri için yerel olarak desteklenmektedir, ancak teknik olarak sizi diğer uygulama türlerinde kullanmaktan alıkoyan hiçbir şey yoktur. Proje dosyalarını manuel olarak düzenleyerek XDT'nin nasıl kullanılacağına dair birçok kılavuz var, ancak harika çalışan bir eklenti buldum: https://visualstudiogallery.msdn.microsoft.com/579d3a78-3bdd-497c-bc21-aa6e6abbc859

Eklenti yalnızca yapılandırmanın kurulumuna yardımcı olur, inşa etmeye gerek yoktur ve çözüm, eklenti veya diğer araçlar gerekmeden başka makinelerde veya bir derleme sunucusunda oluşturulabilir.


Cevap şimdi bu olmalı. Sadece VS 2017'de denedim ve harika çalışıyor. Projeyi yayınlamanıza gerek yok. Sadece inşa et. Sürekli entegrasyon yapımızda kullanım için test projemiz için harika çalışıyor, böylece Selenium testlerini başsız modda çalıştırabiliriz, ancak yerel olarak tarayıcı açılırken çalışırlar. +1.000.000 yapabilirsem.
Greg Burghardt

1

Bu konuyu burada bulduğum çözüm ile çözdüm: http://www.blackwasp.co.uk/SwitchConfig.aspx

Kısaca ifade ettikleri şey: "bir inşa sonrası olay ekleyerek. [...] Aşağıdakileri eklememiz gerekiyor:

if "Debug"=="$(ConfigurationName)" goto :nocopy
del "$(TargetPath).config"
copy "$(ProjectDir)\Release.config" "$(TargetPath).config"
:nocopy

Şimdiye kadarki en kolay yöntem, aşırı düşünenler tarafından berbat edilen çok basit ve gerekli bir işlev olmalıydı! Teşekkürler Janbro.
BoiseBaked

1

SlowCheetah hakkında güzel şeyler duydum ama işe yarayamadı. Şunları yaptım: belirli bir yapılandırma için her birine am etiketi ekledim.

Ör:

<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'UAT|AnyCPU'">
    <OutputPath>bin\UAT\</OutputPath>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <AppConfig>App.UAT.config</AppConfig>
  </PropertyGroup>

Bu, derleme yapılandırmasına göre app.config dosyalarını değiştirmenin başka bir süper basit yolu gibi görünüyor. Mike, standart Hata Ayıklama ve Yayın Yapılandırmaları ile test ettin mi?
BoiseBaked

0

Geliştirme ve derlemeler vb. İçin yapılandırmaları yönetme konusunda biraz araştırma yaptıktan sonra, kendiminkini kullanmaya karar verdim, bitbucket'ta şu adresten kullanıma sundum: https://bitbucket.org/brightertools/contemplate/wiki/Home

Birden çok ortam için bu çoklu konfigürasyon dosyaları, herhangi bir metin tabanlı dosya formatıyla çalışacak temel bir konfigürasyon girişi değiştirme aracıdır.

Bu yardımcı olur umarım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.