Tôi quan tâm đến việc tìm hiểu thêm về cách mọi người tiêm đăng nhập với nền tảng tiêm phụ thuộc. Mặc dù các liên kết bên dưới và các ví dụ của tôi đề cập đến log4net và Unity, nhưng tôi không nhất thiết phải sử dụng một trong hai ví dụ đó. Đối với tiêm phụ thuộc/IOC, tôi có thể sẽ sử dụng MEF vì đó là tiêu chuẩn mà phần còn lại của dự án (lớn) đang được giải quyết.Tiêm phụ thuộc và ghi tên được đặt tên
Tôi rất mới để tiêm phụ thuộc/ioc và khá mới đối với C# và .NET (đã viết rất ít mã sản xuất trong C# /. NET sau 10 năm qua hoặc VC6 và VB6). Tôi đã thực hiện rất nhiều cuộc điều tra về các giải pháp ghi nhật ký khác nhau đang tồn tại ở đó, vì vậy tôi nghĩ rằng tôi có một xử lý tốt trên các bộ tính năng của họ. Tôi chỉ không đủ quen thuộc với cơ chế thực tế của việc tiêm một phụ thuộc (hoặc, có thể nhiều hơn "chính xác", nhận được một phiên bản trừu tượng của một phụ thuộc tiêm).
Tôi đã thấy bài viết khác liên quan đến khai thác gỗ và/hoặc dependency injection như: dependency injection and logging interfaces
What would a Log4Net Wrapper class look like?
again about log4net and Unity IOC config
Câu hỏi của tôi không có đặc biệt để làm với " Làm thế nào để tôi tiêm nền tảng đăng nhập xxx bằng cách sử dụng công cụ ioc yyy? " Thay vào đó, tôi quan tâm đến cách mọi người xử lý gói nền tảng ghi nhật ký (thường là, nhưng không phải lúc nào cũng được đề xuất) và cấu hình (ví dụ: app.config). Ví dụ, sử dụng log4net là một ví dụ, tôi có thể cấu hình (trong app.config) một số người khai thác gỗ và sau đó nhận được những người khai thác gỗ (không phụ thuộc tiêm) trong cách tiêu chuẩn của việc sử dụng mã như thế này:
private static readonly ILog logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
Ngoài , nếu logger của tôi không được đặt tên cho một lớp, nhưng đúng hơn, cho một khu vực chức năng, tôi có thể làm điều này:
private static readonly ILog logger = LogManager.GetLogger("Login");
private static readonly ILog logger = LogManager.GetLogger("Query");
private static readonly ILog logger = LogManager.GetLogger("Report");
vì vậy, tôi đoán rằng tôi "yêu cầu" sẽ là một cái gì đó như thế này:
Tôi muốn cách ly nguồn sản phẩm của mình từ sự phụ thuộc trực tiếp trên nền tảng ghi nhật ký.
Tôi muốn có thể giải quyết một cá thể được đặt tên cụ thể (có thể chia sẻ cùng một cá thể trong số tất cả người yêu cầu cùng một cá thể) trực tiếp hoặc gián tiếp bởi một số loại tiêm phụ thuộc, có thể là MEF.
Tôi không biết nếu tôi gọi đây là một yêu cầu khó khăn, nhưng tôi muốn có khả năng để có được một trình ghi tên có tên (khác với trình ghi lớp) theo yêu cầu. Ví dụ, tôi có thể tạo một logger cho lớp của tôi dựa trên tên lớp, nhưng một phương pháp cần chẩn đoán nặng đặc biệt mà tôi muốn kiểm soát riêng. Nói cách khác, tôi có thể muốn một lớp duy nhất "phụ thuộc" vào hai cá thể logger riêng biệt.
Hãy bắt đầu với số 1. Tôi đã đọc một số bài viết, chủ yếu ở đây trên stackoverflow, về việc có nên quấn hay không. Xem liên kết "thực hành tốt nhất" ở trên và truy cập vào nhận xét của jeffrey hantin về một chế độ xem về lý do tại sao việc tải log4net lại là xấu. Nếu bạn đã bọc (và nếu bạn có thể bọc hiệu quả) bạn sẽ bọc chặt chẽ cho mục đích tiêm/loại bỏ trực tiếp depdency? Hoặc bạn cũng sẽ cố gắng để tóm tắt đi một số hoặc tất cả các thông tin app4config log4net?Giả sử tôi muốn sử dụng System.Diagnostics, tôi có thể muốn triển khai một logger dựa trên giao diện (thậm chí có thể sử dụng giao diện "phổ biến" ILogger/ILog), có lẽ dựa trên TraceSource, để tôi có thể tiêm nó . Bạn sẽ thực hiện giao diện, nói trên TraceSource, và chỉ sử dụng thông tin app.Diagnostics app.config như là?
Something như thế này:
public class MyLogger : ILogger
{
private TraceSource ts;
public MyLogger(string name)
{
ts = new TraceSource(name);
}
public void ILogger.Log(string msg)
{
ts.TraceEvent(msg);
}
}
Và sử dụng nó như thế này:
private static readonly ILogger logger = new MyLogger("stackoverflow");
logger.Info("Hello world!")
Chuyển sang số 2 ... Làm thế nào để giải quyết một trường hợp logger tên cụ thể không? Tôi có nên tận dụng thông tin app.config của nền tảng ghi nhật ký mà tôi chọn (tức là giải quyết logger dựa trên lược đồ đặt tên trong app.config) không? Vì vậy, trong trường hợp của log4net, tôi có thể thích "tiêm" LogManager (lưu ý rằng tôi biết điều này là không thể vì nó là một đối tượng tĩnh)? Tôi có thể bọc LogManager (gọi nó là MyLogManager), cung cấp cho nó một giao diện ILogManager, và sau đó giải quyết giao diện MyLogManager.ILogManager. Các đối tượng khác của tôi có thể có một sự thiếu hụt (nhập khẩu trong MEF parlance) trên ILogManager (Xuất khẩu từ hội đồng nơi nó được thực hiện). Bây giờ tôi có thể có các đối tượng như thế này:
public class MyClass
{
private ILogger logger;
public MyClass([Import(typeof(ILogManager))] logManager)
{
logger = logManager.GetLogger("MyClass");
}
}
Bất kỳ lúc nào ILogManager được gọi, nó sẽ trực tiếp ủy quyền cho log4net của LogManager. Ngoài ra, có thể gói LogManager lấy các cá thể ILogger mà nó dựa trên app.config và thêm chúng vào thùng chứa (a?) MEF theo tên. Sau đó, khi một logger cùng tên được yêu cầu, LogManager được bao bọc sẽ được truy vấn cho tên đó. Nếu ILogger ở đó, nó được giải quyết theo cách đó. Nếu điều này có thể xảy ra với MEF, có lợi ích gì không?
Trong trường hợp này, thực sự, chỉ ILogManager mới được "tiêm" và nó có thể phân phát các cá thể ILogger theo cách mà log4net thường làm. Làm thế nào để loại tiêm (về cơ bản của một nhà máy) so sánh với tiêm các trường hợp logger được đặt tên? Điều này cho phép dễ dàng tận dụng các tập tin app.config của log4net (hoặc nền tảng đăng nhập khác).
Tôi biết rằng tôi có thể đặt tên trường ra khỏi container MEF như thế này:
var container = new CompositionContainer(<catalogs and other stuff>);
ILogger logger = container.GetExportedValue<ILogger>("ThisLogger");
Nhưng làm thế nào để tôi nhận được các trường hợp được đặt tên vào container? Tôi biết về mô hình dựa trên thuộc tính mà tôi có thể có các triển khai khác nhau của ILogger, mỗi cái được đặt tên (thông qua một thuộc tính MEF), nhưng điều đó không thực sự giúp tôi. Có cách nào để tạo ra một cái gì đó giống như một app.config (hoặc một phần trong đó) sẽ liệt kê các logger (tất cả cùng một thực hiện) theo tên và MEF có thể đọc? Có thể/nên có một "quản lý" trung tâm (như MyLogManager) mà giải quyết được đặt tên logger thông qua app.config cơ bản và sau đó chèn logger giải quyết vào container MEF? Bằng cách này nó sẽ có sẵn cho người khác có quyền truy cập vào cùng một container MEF (mặc dù không có kiến thức của MyLogManager về cách sử dụng thông tin app.config của log4net, có vẻ như container sẽ không thể giải quyết bất kỳ logger có tên trực tiếp).
Điều này đã nhận được khá lâu. Tôi hy vọng nó là mạch lạc. Xin vui lòng chia sẻ bất kỳ thông tin cụ thể về cách bạn phụ thuộc tiêm một nền tảng khai thác gỗ (chúng tôi rất có thể xem xét log4net, NLog, hoặc một cái gì đó (hy vọng mỏng) được xây dựng trên System.Diagnostics) vào ứng dụng của bạn.
Bạn đã tiêm "người quản lý" và yêu cầu trở lại các bản ghi nhật ký chưa?
Bạn đã thêm một số thông tin cấu hình của riêng mình vào phần cấu hình của riêng bạn hoặc trong phần cấu hình của nền tảng DI của bạn để dễ dàng hơn/có thể tiêm trực tiếp các bản ghi nhật ký (tức là phụ thuộc vào ILogger chứ không phải ILogManager).
Điều gì về việc có vùng chứa tĩnh hoặc toàn cầu có giao diện ILogManager trong đó hoặc tập hợp các phiên bản ILogger được đặt tên trong đó. Vì vậy, thay vì tiêm theo nghĩa thông thường (thông qua hàm tạo, thuộc tính hoặc dữ liệu thành viên), phụ thuộc ghi nhật ký được giải quyết rõ ràng theo yêu cầu. Đây có phải là cách tốt hay xấu để tiêm phụ thuộc.
Tôi đánh dấu trang này là một wiki cộng đồng vì nó dường như không phải là câu hỏi có câu trả lời rõ ràng. Nếu bất cứ ai cảm thấy khác, hãy thay đổi nó.
Cảm ơn bạn đã trợ giúp!
Dường như MEF và Unity (IoC từ Nhóm mẫu & Thực hành của MS) giống như so sánh táo và cam. Có thể một container IoC thực sự là những gì cần thiết cho vấn đề cụ thể này mà sẽ có các điểm mở rộng để thêm độ phân giải phụ thuộc tùy chỉnh. http://stackoverflow.com/questions/293051/is-mef-a-dependency-injection-framework –