app.config cho một thư viện lớp


83

Tôi không thể thấy tệp app.config được tạo cho thư viện lớp bằng trình hướng dẫn VS2008. Trong nghiên cứu của mình, tôi thấy rằng trong một ứng dụng chỉ tồn tại một app.config.

Có phải là một điều tồi tệ khi thêm một app.config vào thư viện lớp theo cách thủ công hay có bất kỳ phương thức nào khác phục vụ mục đích của app.config trong thư viện lớp không?

Tôi cần lưu trữ thông tin cấu hình log4net bên trong tệp app.config.


3
Bạn có thể đọc tệp cấu hình dự án thực thi từ thư viện của mình.
Akram Shahda

Câu trả lời:


102

Bạn thường không nên thêm app.configtệp vào dự án thư viện lớp; nó sẽ không được sử dụng nếu bạn không bị uốn và xoắn. Nó không ảnh hưởng gì đến dự án thư viện cả - nó sẽ chẳng làm được gì cả.

Thay vào đó, bạn cấu hình ứng dụng đang sử dụng thư viện của bạn; vì vậy thông tin cấu hình được yêu cầu sẽ đến đó. Mỗi ứng dụng có thể sử dụng thư viện của bạn có thể sẽ có các yêu cầu khác nhau, vì vậy điều này cũng thực sự hợp lý.


23
Tốt cho bạn. Tuy nhiên, tôi đã không trả lời câu hỏi của bạn. Bạn rõ ràng có một số loại hệ thống cấu hình tự trồng trong nhà không áp dụng cho người đặt câu hỏi ở đây.
Andrew Barber

1
Tôi có một thư viện lớp Selenium WebDriver mà tôi chạy từ NUnit cho tất cả các trường hợp thử nghiệm của mình. Tôi không muốn phải lo lắng về việc thiết lập cấu hình trong NUnit. Làm thế nào tôi có thể uốn cong và xoắn để hoàn thành việc này? :-)
MacGyver

3
Đã tìm ra ... Nếu sử dụng NUnit, hãy đặt tên tệp app.config của bạn giống với tên tệp dự án * .nunit của bạn. Vì vậy, ví dụ: nếu bạn gọi dự án của mình là "ClassLibraryA.nunit", thì hãy đặt tên cho tệp cấu hình thư viện lớp của bạn là "ClassLibraryA.config". Chúng cũng cần nằm trong cùng một thư mục / thư mục. NUnit thực sự đang sử dụng tệp này làm tệp cấu hình chính .... thêm tham chiếu đến System.Configuration (trong tab .NET) .... và sử dụng mã này: string settingValue = ConfigurationManager.AppSettings ["settingName"];
MacGyver

2
Bạn khuyên bạn nên thiết lập mọi thứ như thế nào khi có các bài kiểm tra tích hợp? Đối với tôi, có vẻ hợp lý khi có một app.config trong thư viện thử nghiệm đó với chuỗi kết nối.
Tomas Jansson

2
Điều gì sẽ xảy ra nếu bạn không thể cấu hình ứng dụng vì bạn không sở hữu nó.
Voltage Spike

50

Tôi không biết tại sao câu trả lời này vẫn chưa được đưa ra:

Nói chung, những người gọi khác nhau của cùng một thư viện sẽ sử dụng các cấu hình khác nhau. Điều này ngụ ý rằng cấu hình phải nằm trong ứng dụng thực thi chứ không phải trong thư viện lớp.

Bạn có thể tạo một app.config trong dự án thư viện lớp. Nó sẽ chứa các cấu hình mặc định cho các mục bạn tạo trong thư viện. Ví dụ, nó sẽ chứa các chuỗi kết nối nếu bạn tạo một mô hình Entity Framework trong thư viện lớp.

Tuy nhiên, các cài đặt này sẽ không được sử dụng bởi ứng dụng thực thi đang gọi thư viện. Thay vào đó, các cài đặt này có thể được sao chép từ tệp thư viện.dll.config vào app.config hoặc web.config của người gọi, để chúng có thể được thay đổi để dành riêng cho người gọi và môi trường mà người gọi là đã triển khai.

Đây là cách nó đã xảy ra với .NET kể từ Ngày 1.


2
Nhưng tôi nên làm gì nếu tôi cần gọi chức năng webserice từ thư viện lớp? VS tạo ra một app.config mặc định nhưng ứng dụng của tôi bị rơi khi cố gắng chức năng webservice cuộc gọi - nó không thể tìm thấy mục cấu hình ...
Laserson

Bạn phải sao chép các phần tử đã được đặt trong thư viện lớp app.config vào app.config hoặc web.config của trình gọi thư viện lớp. Điều này cho phép người gọi kiểm soát cấu hình. Ví dụ: người gọi bây giờ có thể thay đổi URL của dịch vụ mà thư viện lớp của bạn gọi và thư viện lớp của bạn thậm chí sẽ không biết về sự thay đổi này.
John Saunders

6
@John Saunders: "có thể cần" là những từ chính xác. Vì vậy, có thể có những tình huống mà cài đặt cấu hình chỉ khác nhau trên mỗi máy chủ (ví dụ: chuỗi kết nối) và sẽ thuận tiện hơn để dll có cấu hình riêng của nó hơn là sao chép nó nhiều lần cho mọi lắp ráp sử dụng dll. Theo ý kiến ​​của tôi, việc sử dụng ưu tiên Microsofts / .NET không phải là một chén thánh. Nó thực sự phụ thuộc vào điều gì là thuận tiện nhất trong một kịch bản triển khai. Không cần phải nói với Todd, ý kiến ​​của anh ấy cũng quan trọng như ý kiến ​​của bạn hoặc Microsofts.

Tôi thực sự quan tâm đến giải pháp này - nó có vẻ lý tưởng đối với tôi. Có nghĩa là thư viện sẽ mang các cài đặt mặc định, trong khi ứng dụng sẽ có khả năng ghi đè chúng. Bạn có thể mở rộng thêm về cách cài đặt có thể được truyền từ app.config của thư viện sang app.config của assembly đang thực thi hay hướng tôi đến một tài nguyên có liên quan không?
nghiền nát

@crush: Nó được gọi là "sao chép và dán". Tính năng Cài đặt được đánh máy mạnh của .NET có thể giúp ích một chút, vì nó đưa các giá trị mặc định vào hợp ngữ.
John Saunders

43

Jon, rất nhiều ý kiến ​​đã được đưa ra không trả lời chính xác câu hỏi của bạn.

Tôi sẽ đưa ra Ý kiến ​​của mình và sau đó cho bạn biết cách thực hiện chính xác những gì bạn đã yêu cầu.

Tôi không hiểu lý do gì khiến một hội đồng không thể có tệp cấu hình riêng của nó. Tại sao cấp đầu tiên của nguyên tử (đó có phải là từ thực không?) Là cấp ứng dụng? Tại sao không ở cấp độ giải pháp? Đó là một quyết định tùy ý, phỏng đoán tốt nhất và như vậy, một Ý KIẾN. Nếu bạn đang viết một thư viện ghi nhật ký và muốn bao gồm một tệp cấu hình cho nó, tệp đó sẽ được sử dụng trên toàn cầu, tại sao bạn không thể kết nối với chức năng cài đặt tích hợp? Tất cả chúng tôi đã làm được ... cố gắng cung cấp chức năng "mạnh mẽ" cho các nhà phát triển khác. Làm sao? Bằng cách đưa ra các giả định vốn đã chuyển thành các hạn chế. Đó chính xác là những gì MS đã làm với khung cài đặt, vì vậy bạn phải "đánh lừa nó" một chút.

Để trả lời trực tiếp câu hỏi của bạn, chỉ cần thêm tệp cấu hình theo cách thủ công (xml) và đặt tên cho tệp đó phù hợp với thư viện của bạn và bao gồm phần mở rộng "config". Thí dụ:

MyDomain.Mylibrary.dll.Config

Tiếp theo, sử dụng ConfigurationManager để tải tệp và truy cập cài đặt:

string assemblyPath = new Uri(Assembly.GetExecutingAssembly().CodeBase).AbsolutePath;
Configuration cfg = ConfigurationManager.OpenExeConfiguration(assemblyPath);
string result = cfg.AppSettings.Settings["TEST_SETTING"].Value;

Lưu ý rằng điều này hỗ trợ đầy đủ hệ thống phân cấp machine.config, ngay cả khi bạn đã chọn rõ ràng tệp cấu hình ứng dụng. Nói cách khác, nếu cài đặt không có ở đó, nó sẽ phân giải cao hơn. Cài đặt cũng sẽ ghi đè các mục nhập machine.config.


3
-1: Theo bạn, ý kiến ​​của bạn không quan trọng. Sự thật sẽ rất quan trọng. .NET, kể từ Ngày 1, đã được tạo ra để người gọi thư viện xác định cấu hình của các mục trong thư viện. Đó là điều duy nhất có ý nghĩa thực tế đối với cấu hình, vì những người gọi khác nhau của thư viện có thể cần các cấu hình khác nhau.
John Saunders,

19
@JohnSaunders "những người gọi khác nhau của thư viện có thể cần các cấu hình khác nhau." Chính xác, họ "có thể" cần các cấu hình khác nhau và logic của bạn có ý nghĩa hoàn hảo trong mọi trường hợp khi cấu hình phụ thuộc vào người gọi. Nhưng có một số trường hợp cấu hình được sử dụng nội bộ cho thư viện lớp và cấu hình hoàn toàn giống nhau, bất kể người gọi là gì. Nếu bạn có 10 ứng dụng sử dụng một thư viện, thì việc sao chép và dán chính xác cùng một cấu hình vào 10 tệp cấu hình sẽ trở nên tồi tệ hơn.
wired_in

3
@ToddBeaulieu: Tôi nghĩ từ bạn muốn là 'nguyên tử'.
nicodemus 13

3
Trong một kiến ​​trúc plugin, sẽ thực sự có ý nghĩa nếu tất cả các plugin đều có tệp cấu hình riêng của chúng.
Davatar

4
@RMuesi Noone cho biết nó không bao giờ thay đổi, chỉ là nó không phụ thuộc vào người gọi của thư viện. Cấu hình có thể thay đổi tùy thuộc vào việc bạn đang gỡ lỗi thư viện so với bản phát hành sản xuất. Nó có thể thay đổi tùy thuộc vào môi trường bạn đang xây dựng cho vv
wired_in

6

Trên thực tế, thư viện lớp mà bạn đang triển khai, đang truy xuất thông tin từ app.config bên trong ứng dụng đang sử dụng nó, vì vậy, cách đúng nhất để triển khai cấu hình cho các thư viện lớp tại .net trong VS là chuẩn bị app.config trong ứng dụng để định cấu hình mọi thứ mà nó sử dụng, như cấu hình thư viện.

Tôi đã làm việc một chút với log4net và tôi thấy rằng người chuẩn bị ứng dụng luôn có phần dành cho cấu hình log4net bên trong main app.config .

Tôi hy vọng bạn tìm thấy thông tin này hữu ích.

Hẹn gặp bạn và gửi bình luận về giải pháp bạn tìm thấy.

BIÊN TẬP:

Tại liên kết tiếp theo, bạn có app.config với phần dành cho log4net:

http://weblogs.asp.net/tgraham/archive/2007/03/15/a-realistic-log4net-config.aspx


2
+1 Chính xác; Các app.configđược nạp từ các chương trình thực tế mà cuối cùng chạy ... không phải là thư viện lớp riêng biệt. Thực ra hơi khó hiểu là nhiều người không biết sự thật cơ bản này.
Andrew Barber

Có thể mọi người đến từ ngôn ngữ Java và ở đó bạn có một tệp log4java.properties và một tệp thuộc tính riêng cho ứng dụng của mình.
Amedio

6

Nếu bạn muốn định cấu hình ghi nhật ký dự án của mình bằng log4Net, trong khi sử dụng thư viện lớp, thực tế không cần bất kỳ tệp cấu hình nào. Bạn có thể định cấu hình trình ghi log4net của mình trong một lớp và có thể sử dụng lớp đó làm thư viện.

Vì log4net cung cấp tất cả các tùy chọn để cấu hình nó.

Vui lòng tìm mã bên dưới.

public static void SetLogger(string pathName, string pattern)
        {
            Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();

            PatternLayout patternLayout = new PatternLayout();
            patternLayout.ConversionPattern = pattern;
            patternLayout.ActivateOptions();

            RollingFileAppender roller = new RollingFileAppender();
            roller.AppendToFile = false;
            roller.File = pathName;
            roller.Layout = patternLayout;
            roller.MaxSizeRollBackups = 5;
            roller.MaximumFileSize = "1GB";
            roller.RollingStyle = RollingFileAppender.RollingMode.Size;
            roller.StaticLogFileName = true;
            roller.ActivateOptions();
            hierarchy.Root.AddAppender(roller);

            MemoryAppender memory = new MemoryAppender();
            memory.ActivateOptions();
            hierarchy.Root.AddAppender(memory);

            hierarchy.Root.Level = log4net.Core.Level.Info;
            hierarchy.Configured = true;
      }

Bây giờ thay vì gọi XmlConfigurator.Configure (FileInfo mới ("app.config")), bạn có thể gọi trực tiếp SetLogger với đường dẫn và mẫu mong muốn để đặt trình ghi nhật ký trong chức năng khởi động ứng dụng Global.asax.

Và sử dụng mã dưới đây để ghi lại lỗi.

        public static void getLog(string className, string message)
        {
            log4net.ILog iLOG = LogManager.GetLogger(className);
            iLOG.Error(message);    // Info, Fatal, Warn, Debug
        }

Bằng cách sử dụng mã sau, bạn không cần phải viết một dòng nào trong ứng dụng web.config cũng như bên trong thư viện app.config.


2
tôi cảm thấy đây là câu trả lời hay nhất ... thay vì thảo luận về việc có nên cho phép tệp cấu hình cho một thư viện hay không ... câu trả lời này trả lời câu hỏi của OP về việc sử dụng Log4net
saurav

1
Mặc dù câu hỏi sử dụng log4net làm ví dụ, câu hỏi thực tế là về cấu hình nói chung. Tôi muốn nói rằng các câu trả lời về log4net thực sự không liên quan.
binki

4

Trên thực tế, trong một số trường hợp hiếm hoi, bạn có thể lưu trữ app.config trong các thư viện lớp (bằng cách thêm thủ công) và phân tích cú pháp nó bằng OpenExeConfiguration .

 var fileMap =
    new ExeConfigurationFileMap {ExeConfigFilename = 
    @"C:\..somePath..\someName.config"};
 System.Configuration.Configuration config =
    ConfigurationManager.OpenMappedExeConfiguration(fileMap, 
    ConfigurationUserLevel.None);

Bạn thực sự nên ước tính nhu cầu thực sự của việc này. Đối với dữ liệu trừu tượng, nó không phải là giải pháp tốt nhất, nhưng "Phần cấu hình" có thể rất hữu ích !!

Ví dụ: chúng tôi đã tổ chức kiến ​​trúc N-Tier WCF được tách riêng mà không có bất kỳ siêu dữ liệu nào, chỉ đơn giản bằng cách sử dụng Unity Container và Injection Factory dựa trên Channel Factory T. Chúng tôi đã thêm dll externall ClassLibrary chỉ với [Hợp đồng dịch vụ] Giao diện và app.config chung theo thứ tự để đọc các điểm cuối từ phần khách hàng và dễ dàng thêm / thay đổi chúng tại một nơi.


3

Bạn muốn thêm App.config vào thư viện lớp kiểm tra của mình , nếu bạn đang sử dụng trình theo dõi / ghi nhật ký. Nếu không, không có gì được ghi lại khi bạn chạy thử nghiệm thông qua một trình chạy thử nghiệm như TestDriven.Net.

Ví dụ: tôi sử dụng TraceSourcetrong các chương trình của mình, nhưng việc chạy các bài kiểm tra không ghi lại bất kỳ thứ gì trừ khi tôi thêm tệp App.config có cấu hình trace / log vào thư viện lớp kiểm tra.

Nếu không, việc thêm App.config vào thư viện lớp sẽ không làm được gì cả.


2

Câu trả lời của bạn cho việc tạo app.config không thủ công là tab Cài đặt / Thuộc tính dự án Visual Studio.

Khi bạn thêm cài đặt và lưu, app.config của bạn sẽ được tạo tự động. Tại thời điểm này, một loạt mã được tạo trong không gian tên { yourclasslibrary .Properties } chứa các thuộc tính tương ứng với cài đặt của bạn. Bản thân các cài đặt sẽ được đặt trong cài đặt applicationSettings của app.config.

 <configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
        <section name="ClassLibrary.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup>
</configSections>
<applicationSettings>
    <ClassLibrary.Properties.Settings>
        <setting name="Setting1" serializeAs="String">
            <value>3</value>
        </setting>
    </BookOneGenerator.Properties.Settings>
</applicationSettings>

Nếu bạn đã thêm cài đặt trong phạm vi Ứng dụng có tên là Setting1 = 3 thì một thuộc tính có tên là Setting1 sẽ được tạo. Các thuộc tính này đang trở thành phần biên dịch của tệp nhị phân và chúng được trang trí bằng một Thuộc tính mặc định được đặt thành giá trị bạn đã chỉ định tại thời điểm phát triển.

     [ApplicationScopedSetting]
    [DebuggerNonUserCode]
    [DefaultSettingValue("3")]
    public string Setting1
    {
        get
        {
            return (string)this["Setting1"];
        }
    }

Vì vậy, giống như trong mã thư viện lớp của bạn, bạn sử dụng các thuộc tính này nếu cài đặt tương ứng không tồn tại trong tệp cấu hình thời gian chạy, nó sẽ dự phòng để sử dụng giá trị mặc định. Bằng cách đó, ứng dụng sẽ không gặp sự cố vì thiếu mục cài đặt, điều này rất khó hiểu lần đầu tiên khi bạn không biết những thứ này hoạt động như thế nào. Bây giờ, bạn đang tự hỏi mình làm thế nào có thể chỉ định giá trị mới của riêng chúng ta trong thư viện đã triển khai và tránh sử dụng giá trị cài đặt mặc định?

Điều đó sẽ xảy ra khi chúng ta định cấu hình đúng app.config của tệp thực thi. Hai bước. 1. chúng tôi làm cho nó biết rằng chúng tôi sẽ có một phần cài đặt cho thư viện lớp đó và 2. với những sửa đổi nhỏ, chúng tôi dán tệp cấu hình của thư viện lớp vào cấu hình thực thi. (có một phương pháp mà bạn có thể giữ tệp cấu hình thư viện lớp bên ngoài và bạn chỉ cần tham chiếu nó từ cấu hình của tệp thực thi.

Vì vậy, bạn có thể có app.config cho thư viện lớp nhưng sẽ vô ích nếu bạn không tích hợp nó đúng cách với ứng dụng mẹ. Xem ở đây những gì tôi đã viết cách đây: liên kết


1

Không có tự động thêm tệp app.config khi bạn thêm dự án thư viện lớp vào giải pháp của mình.

Theo hiểu biết của tôi, không có dấu hiệu chống lại việc làm như vậy thủ công. Tôi nghĩ rằng đây là một cách sử dụng phổ biến.

Về cấu hình log4Net, bạn không cần phải đặt cấu hình vào app.config, bạn có thể có tệp conf chuyên dụng trong dự án của mình cũng như tệp app.config cùng một lúc.

liên kết này http://logging.apache.org/log4net/release/manual/configuration.html sẽ cung cấp cho bạn ví dụ về cả hai cách (phần trong app.config và tệp conf log4net độc lập)


Không có hại gì khi thêm một app.configdự án thư viện, không. Nhưng nó sẽ không được sử dụng.
Andrew Barber

1
@AndrewBarber Nó sẽ được sử dụng trong một dự án thử nghiệm. Xem stackoverflow.com/a/31389495
binki

0

Tôi khuyên bạn nên sử dụng Properties.Settings để lưu trữ các giá trị như ConnectionStrings, v.v. bên trong thư viện lớp. Đây là nơi tất cả các chuỗi kết nối được lưu trữ theo gợi ý từ visual studio khi bạn cố gắng thêm bộ điều hợp bảng chẳng hạn. nhập mô tả hình ảnh ở đây

Và sau đó họ sẽ có thể truy cập được bằng cách sử dụng mã này ở mọi nơi trong thư viện clas

var cs=  Properties.Settings.Default.[<name of defined setting>];
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.