Hãy để chúng tôi nói rằng tôi đang tạo một ứng dụng có tên ConsoleApp2 .
Do một số thư viện bên thứ ba tôi đang sử dụng, tệp app.config mặc định của tôi đang tạo mã như
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
Đó là bởi vì giải pháp của tôi tham chiếu các phiên bản khác nhau của một thư viện, vì vậy nó cần nói với mọi người: " Này, nếu bạn tìm bất kỳ oldVersion nào của thư viện này, chỉ cần sử dụng newVersion ". Và đó là tất cả các quyền.
Vấn đề là tôi muốn xác định một tệp cấu hình riêng biệt "test.exe.config" trong đó tôi có một số cài đặt và thoát khỏi tệp được tạo tự động.
Để cho Ứng dụng của tôi biết về tệp cấu hình mới, tôi đang sử dụng mã như
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "test.exe.config");
Và nó hoạt động (gần như) hoàn hảo. Và tôi đã viết ở đó " gần như " vì mặc dù <appSettings>
phần này đang được đọc chính xác, <runtime>
phần đó không được xem trong tệp cấu hình tùy chỉnh của tôi, nhưng Ứng dụng tìm nó trong tệp cấu hình mặc định, đó là một vấn đề vì tôi muốn có thể xóa cái đó sau.
Vì vậy, làm thế nào tôi có thể yêu cầu Ứng dụng của mình đọc <runtime>
thông tin từ tệp cấu hình tùy chỉnh của mình?
Làm thế nào để tái tạo vấn đề
Một mẫu đơn giản để tái tạo vấn đề của tôi như sau:
Tạo một thư viện có tên ClassL Library2 ( .Net Framework v4.6 ) với một lớp duy nhất như sau
using Newtonsoft.Json.Linq;
using System;
namespace ClassLibrary2
{
public class Class1
{
public Class1()
{
var json = new JObject();
json.Add("Succeed?", true);
Reash = json.ToString();
}
public String Reash { get; set; }
}
}
Lưu ý tham chiếu đến gói Newtonsoft . Cái được cài đặt trong thư viện là v10.0.2 .
Bây giờ hãy tạo Ứng dụng Console có tên ConsoleApp2 ( .Net Framework v4.6 ) với một lớp có tên là Chương trình với nội dung đơn giản như sau:
using System;
using System.Configuration;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "test.exe.config");
var AppSettings = ConfigurationManager.AppSettings;
Console.WriteLine($"{AppSettings.Count} settings found");
Console.WriteLine($"Calling ClassLibrary2: {Environment.NewLine}{new ClassLibrary2.Class1().Reash}");
Console.ReadLine();
}
}
}
Ứng dụng này cũng đã cài đặt Newtonsoft , nhưng trong phiên bản khác v12.0.3 .
Xây dựng ứng dụng trong chế độ Gỡ lỗi. Sau đó, trong thư mục ConsoleApp2 / ConsoleApp2 / bin / Debug tạo một tệp có tên test.exe.config với nội dung sau
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<appSettings>
<add key="A" value="1"/>
<add key="B" value="1"/>
<add key="C" value="1"/>
</appSettings>
</configuration>
và lưu ý rằng trong cùng thư mục Debug đó cũng có tệp cấu hình mặc định ConsoleApp2.exe.config có nội dung như
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Nếu thời điểm này bạn chạy ứng dụng, nó sẽ biên dịch mà không gặp vấn đề gì và bạn sẽ thấy Bảng điều khiển như
Lưu ý rằng cài đặt (3) đã được đọc chính xác từ tệp cấu hình tùy chỉnh của tôi. Càng xa càng tốt...
Bây giờ đổi tên tệp cấu hình mặc định thành một cái gì đó như _ConsoleApp2.exe.config và chạy lại ứng dụng. Bây giờ bạn sẽ nhận được một FileLoadException .
Vì vậy, một lần nữa, làm thế nào tôi có thể yêu cầu Ứng dụng của tôi đọc <runtime>
thông tin từ tệp cấu hình tùy chỉnh của tôi?
Cơ sở lý luận
Lý do tôi đang tìm kiếm một câu trả lời cho câu hỏi này như sau:
Khi chúng tôi phát hành ứng dụng của mình, chúng tôi đặt tất cả các tệp .exe và dll vào một thư mục và tệp cấu hình tùy chỉnh của chúng tôi (có cài đặt, v.v.) trong một tệp khác, nơi khách hàng của chúng tôi có các tệp tương tự.
Trong thư mục chứa các tệp .exe và. Chúng tôi cố gắng giữ càng ít càng tốt, vì vậy tôi được yêu cầu tìm cách thoát khỏi ConsoleApp2.exe.config nếu có thể. Bây giờ, vì các ràng buộc đã nói ở trên được ghi trong tệp cấu hình đó, tôi chỉ thử chuyển thông tin đó sang tệp cấu hình tùy chỉnh của chúng tôi ... nhưng cho đến nay tôi đã không đạt được: các chuyển hướng liên kết luôn được cố gắng đọc từ ConsoleApp2.exe .config , vì vậy ngay sau khi xóa, tôi sẽ có ngoại lệ ...
<runtime>
phần từ cấu hình khác, nhưng sự cố xảy ra do cách bạn quản lý cấu hình chung. Nếu bạn quản lý cấu hình chung theo một cách khác, vấn đề này không còn phù hợp nữa. Vui lòng kiểm tra câu trả lời của tôi và xem xét sử dụng các biến đổi cấu hình thay vì điều chỉnh thời gian chạy.