Cách chọn app.config khác nhau cho một số cấu hình bản dựng


115

Tôi có một dự án kiểu dll chứa các bài kiểm tra tích hợp MSTest. Trên máy của tôi, các bài kiểm tra đều vượt qua và tôi muốn điều tương tự xảy ra trên máy chủ CI (tôi sử dụng TeamCity). Nhưng các thử nghiệm không thành công, vì tôi cần điều chỉnh một số cài đặt trong app.config. Đây là lý do tại sao tôi nghĩ đến việc có một tệp app.config thứ hai riêng biệt sẽ giữ các cài đặt cho máy chủ CI.

Vì vậy, tôi muốn có

/ Sln
 / Proj
  app.config (tôi nghĩ VS yêu cầu điều này)
  app.Release.config (Đây là một tệp cấu hình độc lập độc lập)

Vì vậy, nếu tôi chọn Cấu hình phát hành trong cấu hình xây dựng trên CI, tôi muốn sử dụng tệp app.Release.config thay vì app.config

Vấn đề
Điều này dường như không đơn giản đối với các dự án kiểu .dll đơn giản. Đối với các dự án web, tôi có thể thực hiện chuyển đổi cấu hình web. Tôi đã tìm thấy một bản hack làm thế nào để thực hiện những chuyển đổi này cho một dự án kiểu dll, nhưng tôi không phải là một fan hâm mộ lớn của hack.

Câu hỏi
Cách tiếp cận tiêu chuẩn để chỉnh sửa tệp app.config tùy thuộc vào cấu hình xây dựng cho các dự án .NET (chẳng hạn như Gỡ lỗi, Phát hành, ...) là gì?

Câu trả lời:


154

Sử dụng plugin SlowCheetah . Để biết thêm tùy chọn và chi tiết về cách sử dụng SlowCheetah, hãy đọc tiếp.

Như bạn đã nhận thấy, không có cách mặc định và dễ dàng để sử dụng các tệp cấu hình khác nhau cho dự án kiểu Thư viện (.dll) . Nguyên nhân là do tư duy hiện nay là: "Bạn không cần"! Các nhà phát triển khung cho rằng bạn cần cấu hình cho tệp thực thi: có thể là bảng điều khiển, máy tính để bàn, web, ứng dụng di động hoặc thứ gì đó khác. Nếu bạn bắt đầu cung cấp cấu hình cho một dll , bạn có thể kết thúc với một thứ mà tôi có thể gọi là địa ngục cấu hình . Bạn có thể không còn hiểu (dễ dàng) tại sao biến này và biến đó có những giá trị kỳ lạ đến như vậy dường như không biết từ đâu.

"Chờ đã", - bạn có thể nói, "nhưng tôi cần cái này để thử nghiệm tích hợp / đơn vị của mình, và nó là một thư viện!". Và đó là sự thật và đây là những gì bạn có thể làm (chỉ chọn một, không trộn lẫn):

1. SlowCheetah - chuyển đổi tệp cấu hình hiện tại

Bạn có thể cài đặt SlowCheetah - một trình cắm thêm Visual Studio thực hiện tất cả các chuyển đổi (hoặc chuyển đổi) XML cấp thấp cho bạn. Cách nó hoạt động, ngắn gọn:

  • Cài đặt SlowCheetah và khởi động lại Visual Studio (Visual Studio> Công cụ> Tiện ích mở rộng và Cập nhật ...> Trực tuyến> Thư viện Visual Studio> tìm kiếm "Slow Cheetah")
  • Xác định cấu hình giải pháp của bạn ( Gỡ lỗiBản phát hành ở đó theo mặc định), bạn có thể thêm nhiều hơn nữa (nhấp chuột phải vào giải pháp trong Giải pháp Explorer > Trình quản lý Cấu hình ... > Cấu hình Giải pháp Hoạt động > Mới ...
  • Thêm tệp cấu hình nếu cần
  • Nhấp chuột phải vào tệp cấu hình> Thêm chuyển đổi
    • Thao tác này sẽ tạo các tệp Chuyển đổi - một tệp cho mỗi cấu hình của bạn
    • Các tệp chuyển đổi hoạt động như bộ chèn / bộ biến đổi, chúng tìm thấy mã XML cần thiết trong tệp cấu hình ban đầu và đưa vào các dòng mới hoặc biến đổi giá trị cần thiết, bất cứ điều gì bạn yêu cầu nó làm

2. Làm quen với tệp .proj - sao chép-đổi tên một tệp cấu hình hoàn toàn mới

Ban đầu được lấy từ đây . Đó là một nhiệm vụ MSBuild tùy chỉnh mà bạn có thể nhúng vào tệp Visual Studio .proj . Sao chép và dán đoạn mã sau vào tệp dự án

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

Bây giờ, tạo một thư mục trong dự án có tên Configvà thêm tập tin mới có: App.Debug.config , App.Release.config và vân vân. Bây giờ, tùy thuộc vào cấu hình của bạn, Visual Studio sẽ chọn tệp cấu hình từ một Configthư mục và sao chép-đổi tên tệp đó vào thư mục đầu ra. Vì vậy, nếu bạn đã chọn dự án PatternPA.Test.Integration và cấu hình Gỡ lỗi , trong thư mục đầu ra sau khi xây dựng, bạn sẽ tìm thấy tệp PatternPA.Test.Integration.dll.config đã được sao chép Config\App.Debug.configvà đổi tên sau đó.

Đây là một số lưu ý bạn có thể để lại trong các tệp cấu hình

<?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>

Trong Visual Studio, bạn có thể có một cái gì đó như thế này

Cấu trúc dự án

3. Sử dụng các tệp kịch bản bên ngoài Visual Studio

Mỗi công cụ xây dựng (như NAnt , MSBuild ) sẽ cung cấp khả năng chuyển đổi tệp cấu hình tùy thuộc vào cấu hình. Điều này hữu ích nếu bạn xây dựng giải pháp của mình trên máy xây dựng, nơi bạn cần kiểm soát nhiều hơn về những gì và cách bạn chuẩn bị sản phẩm để phát hành.

Ví dụ: bạn có thể sử dụng tác vụ của dll xuất bản web để chuyển đổi bất kỳ tệp cấu hình nào

<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>

Giải pháp thứ hai của bạn hoạt động tốt, nhưng không phải để xuất bản các dự án web. Sau khi xuất bản một dự án ASP.NET, web.config gốc được xuất bản.
Massood Khaari

3
@MassoodKhaari bạn cần đảm bảo tác vụ này được gọi cho mục tiêu xuất bản. Khi bạn xuất bản một dự án, một mục tiêu xây dựng riêng được gọi, mục tiêu này có thể không gọi theo AfterBuildmục tiêu mặc định . Trong quá trình biên dịch điển hình, AfterBuildđích được gọi theo mặc định. Nên có một sửa chữa nhanh chóng cho xuất bản trường hợp
oleksii

1
Đã sử dụng phương pháp thứ hai của bạn (kinda). Đã đến thuộc tính dự án và chỉnh sửa BeforeBuild để sao chép nội App.<Target>.configdung App.configtrong dự án , không phải dir đầu ra.
SparK

@oleksii Bạn nói đúng. Nhưng tôi vẫn không thể tìm thấy mục tiêu mà quá trình xuất bản web của tôi đang sử dụng (trong Visual Studio 2013).
Massood Khaari

1
Tôi đang sử dụng phương pháp thứ hai, nhưng cần thêm điều kiện vào đích AfterBuild để đảm bảo tệp thực sự tồn tại trước khi xóa. Tôi có cấu hình xây dựng Gỡ lỗi, về cơ bản chỉ sử dụng tệp App.config mặc định, nhưng tôi không có App.Debug.config, có nghĩa là bước xây dựng sẽ không thành công. Tôi chỉ thêm vào Condition="Exists('$(ProjectDir)App.$(Configuration).config')".
Siewers

23

Bạn có thể thử cách tiếp cận sau:

  1. Nhấp chuột phải vào dự án trong Solution Explorer và chọn Unload Project .
  2. Dự án sẽ được dỡ bỏ. Nhấp chuột phải vào dự án một lần nữa và chọn Edit <YourProjectName> .csproj .
  3. Bây giờ bạn có thể chỉnh sửa tệp dự án bên trong Visual Studio.
  4. Xác định vị trí trong tệp * .csproj nơi có tệp cấu hình ứng dụng của bạn. Nó sẽ giống như sau:
    <ItemGroup>
        <Không bao gồm = "App.config" />
    </ItemGroup>
  1. Thay thế dòng này bằng dòng sau:
    <ItemGroup Condition = "'$ (Cấu hình)' == 'Gỡ lỗi'">
        <Không bao gồm = "App.Debug.config" />
    </ItemGroup>

    <ItemGroup Condition = "'$ (Cấu hình)' == 'Phát hành'">
        <Không bao gồm = "App.Release.config" />
    </ItemGroup>

Tôi chưa thử cách tiếp cận này với app.configtệp, nhưng nó hoạt động tốt với các mục khác của dự án Visual Studio. Bạn có thể tùy chỉnh quá trình xây dựng theo bất kỳ cách nào bạn muốn. Dù sao, hãy cho tôi biết kết quả.


Tnx cho câu trả lời, nhưng điều này không hoạt động với app.config. VS yêu cầu bắt buộc app.configvà không áp dụng cấu hình phát hành nếu tôi sử dụng VS build hoặc Teamcity VS sln build runner.
oleksii

2
Dưới đây giải thích cách thực hiện: Bật app.debug.config app.release.config
Gabrielizalo

1
Tại sao câu trả lời này có rất nhiều phiếu bầu? Tôi đã thử nó và nó không hoạt động. Thực tế ở cả chế độ gỡ lỗi và phát hành không có tệp App.config và do đó, không có tệp tương ứng trong thư mục đầu ra. Các tệp App.Debug.config và App.Release.config không có bất kỳ ý nghĩa nào đối với Visual Studio.
MarkusParker

Nó không hoạt động: Không thể mở .csproj, thông báo lỗi "các phần tử bên ngoài Phần tử mục tiêu phải có: Bao gồm, Cập nhật hoặc Loại bỏ"
Elo

12

Bạn nên xem xét ConfigGen . Nó được phát triển cho mục đích này. Nó tạo một tệp cấu hình cho mỗi máy triển khai, dựa trên tệp mẫu và tệp cài đặt. Tôi biết rằng điều này không trả lời câu hỏi của bạn một cách cụ thể, nhưng nó có thể giải đáp vấn đề của bạn.

Vì vậy, thay vì Gỡ lỗi, Phát hành, v.v., bạn có thể có Kiểm tra, UAT, Sản xuất, v.v. Bạn cũng có thể có các cài đặt khác nhau cho từng máy nhà phát triển, để bạn có thể tạo cấu hình cụ thể cho máy nhà phát triển của mình và thay đổi nó mà không ảnh hưởng đến việc triển khai của bất kỳ máy nào khác .

Một ví dụ về cách sử dụng có thể là ...

<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>

Nếu bạn đặt tệp này vào tệp .csproj và bạn có các tệp sau ...

$(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>

... thì đây sẽ là kết quả ...

Từ lệnh đầu tiên, một tệp cấu hình được tạo cho mỗi môi trường được chỉ định trong tệp xls, được đặt trong thư mục đầu ra $ (SolutionDir) ConfigGen

.../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>

Từ lệnh thứ hai, App.config cục bộ được sử dụng trên máy dev của bạn sẽ được thay thế bằng cấu hình đã tạo được chỉ định bởi công tắc cục bộ (-l) và công tắc tên tệp (-n).


2
Tnx cho câu trả lời, điều này có vẻ không tệ. Nhưng có một số hạn chế, nó chỉ hiển thị 75 lượt tải xuống (do đó nó không phải dành cho người lớn) và nó chỉ hoạt động với .xls hoặc .xlsx. Tôi không thực sự muốn phụ thuộc vào một định dạng tài liệu tùy chỉnh khác cho các hoạt động đơn giản. Tôi đang tìm kiếm một cách tiếp cận tiêu chuẩn hơn ...
oleksii

2
Điểm hợp lý, mặc dù nó nói 194 lượt tải xuống trên CodePlex, nhưng xls là một bảng tính, hầu như không phải là một định dạng tùy chỉnh và tôi biết ba Ngân hàng Đầu tư lớn đã chấp thuận điều này để sử dụng, vì vậy nếu nó đủ tốt cho họ ... Ngoài ra, một của các tính năng hiện được yêu cầu là sử dụng xml cho cài đặt. Nó gần như đã sẵn sàng, nhưng tôi vẫn thích cách tiếp cận bảng tính hơn. Nó là dễ dàng hơn nhiều để xem tất cả các thiết lập cho mọi môi trường trong một cái nhìn bảng
Daniel Dyson

Hiện chúng tôi đang trong giai đoạn cuối của việc thử nghiệm một phiên bản configGen có thể được sử dụng để tạo các tệp văn bản thuần túy, không chỉ là xml. Vì vậy, nếu bạn muốn tạo css, sql, javascript, v.v. theo môi trường cụ thể, hãy theo dõi trang web configGen
Daniel Dyson

cảm ơn Daniel về giải pháp, đây chính xác là những gì tôi đang tìm kiếm. Tôi sẽ cho nó nó một cơ hội.
Bhupinder Singh

10

Sử dụng phương pháp tương tự như Romeo, tôi đã điều chỉnh nó thành Visual Studio 2010:

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

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

Ở đây bạn cần giữ cả hai tệp App.config trong các thư mục khác nhau (appDebug và appRelease). Tôi đã thử nghiệm nó và nó hoạt động tốt!


3

Tôi đang sử dụng công cụ XmlPreprocess để thao tác cấu hình tệp. Nó đang sử dụng một tệp ánh xạ cho nhiều môi trường (hoặc nhiều mục tiêu xây dựng trong trường hợp của bạn). Bạn có thể chỉnh sửa tệp ánh xạ bằng Excel. Nó rất dễ sử dụng.


3

SlowCheetah và FastKoala từ VisualStudio Gallery dường như là những công cụ rất tốt giúp giải quyết vấn đề này.

Tuy nhiên, nếu bạn muốn tránh các phần bổ trợ hoặc sử dụng các nguyên tắc mà chúng triển khai rộng rãi hơn trong suốt quá trình xây dựng / tích hợp thì việc thêm phần này vào tệp msbuild * proj của bạn là một cách khắc phục ngắn gọn.

Lưu ý: đây ít nhiều là sự làm lại câu trả lời số 2 của @ oleksii.

Điều này hoạt động cho các dự án .exe và .dll:

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

Điều này hoạt động cho các dự án web:

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

Lưu ý rằng bước này xảy ra ngay cả trước khi quá trình xây dựng phù hợp bắt đầu. Việc chuyển đổi tệp cấu hình xảy ra trong thư mục dự án. Vì vậy, web.config đã chuyển đổi có sẵn khi bạn gỡ lỗi (một nhược điểm của SlowCheetah).

Hãy nhớ rằng nếu bạn tạo thư mục App_Config (hoặc bất cứ thứ gì bạn chọn để gọi nó), các tệp cấu hình trung gian khác nhau phải có Hành động xây dựng = Không và Sao chép vào Thư mục đầu ra = Không sao chép.

Điều này kết hợp cả hai tùy chọn thành một khối. Một trong những thích hợp được thực hiện dựa trên các điều kiện. Nhiệm vụ TransformXml được xác định trước tiên:

<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>


Tôi vừa thử điều này trong Visual Studio 2017 và nó không hoạt động. Bắn. Tôi thực sự hy vọng nó sẽ hoạt động, bởi vì nó có vẻ là cách dễ thực hiện nhất.
Greg Burghardt

Tác vụ TransformXml không được xác định trong các mẫu. Tôi đang thêm một mục nhập. Bạn có thể xác định nó trong tệp mycustom.targets được đưa vào tất cả các dự án khởi chạy trong giải pháp của bạn.
Eniola

@GregBurghardt, bạn có muốn thử ngay không?
Eniola

Tôi có lẽ sẽ thử. Tôi đã cài đặt plugin Config Transform cho Visual Studio và nó hoạt động rất tốt. Tôi thực sự tự hỏi nếu plugin về cơ bản làm những gì câu trả lời của bạn.
Greg Burghardt

Được rồi, hãy cho tôi biết nó diễn ra như thế nào.
Eniola

1

Xem liệu công cụ chuyển đổi XDT (web.config) có thể giúp bạn không. Hiện tại, nó chỉ được hỗ trợ nguyên bản cho các dự án web, nhưng về mặt kỹ thuật, không có gì ngăn cản bạn sử dụng nó trong các loại ứng dụng khác. Có nhiều hướng dẫn về cách sử dụng XDT bằng cách chỉnh sửa thủ công các tệp dự án, nhưng tôi thấy một plugin hoạt động tuyệt vời: https://visualstudiogallery.msdn.microsoft.com/579d3a78-3bdd-497c-bc21-aa6e6abbc859

Plugin chỉ giúp thiết lập cấu hình, nó không cần thiết để xây dựng và giải pháp có thể được xây dựng trên các máy khác hoặc trên máy chủ xây dựng mà không cần plugin hoặc bất kỳ công cụ nào khác.


Đây sẽ là câu trả lời ngay bây giờ. Chỉ cần thử nó trên VS 2017 và nó hoạt động như một sự quyến rũ. Bạn không cần phải xuất bản dự án. Chỉ cần xây dựng nó. Hoạt động tốt cho dự án thử nghiệm của chúng tôi để sử dụng trong bản dựng tích hợp liên tục của chúng tôi để chúng tôi có thể chạy các thử nghiệm Selenium ở chế độ không sử dụng, nhưng chúng chạy cục bộ khi mở trình duyệt. +1.000.000 nếu tôi có thể.
Greg Burghardt

1

Tôi đã giải quyết chủ đề này bằng giải pháp mà tôi đã tìm thấy ở đây: http://www.blackwasp.co.uk/SwitchConfig.aspx

Tóm lại, những gì họ nói ở đó là: "bằng cách thêm một sự kiện sau xây dựng. [...] Chúng ta cần thêm những điều sau:

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

Cho đến nay, phương pháp dễ dàng nhất để thực hiện những gì lẽ ra phải là một chức năng rất đơn giản và thiết yếu đã bị những kẻ suy nghĩ quá mức làm sai lệch! Cảm ơn Janbro.
BoiseBaked

1

Tôi đã nghe những điều tốt đẹp về SlowCheetah, nhưng không thể làm cho nó hoạt động. Tôi đã làm như sau: thêm thẻ am vào mỗi thẻ cho một cấu hình cụ thể.

Ví dụ:

<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>

Đây có vẻ như là một cách siêu đơn giản khác để thay đổi tệp app.config theo cấu hình bản dựng. Mike, bạn đã kiểm tra với Cấu hình gỡ lỗi và phát hành tiêu chuẩn chưa?
BoiseBaked

0

Sau một số nghiên cứu về việc quản lý cấu hình để phát triển và xây dựng, v.v., tôi quyết định tự triển khai, tôi đã cung cấp nó trên bitbucket tại: https://bitbucket.org/brightertools/contemplate/wiki/Home

Nhiều tệp cấu hình này cho nhiều môi trường, là công cụ thay thế mục nhập cấu hình cơ bản sẽ hoạt động với mọi định dạng tệp dựa trên văn bản.

Hi vọng điêu nay co ich.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.