Cách tiếp cận đơn giản nhất để đăng nhập vào Prism là ghi đè thuộc tính LoggerFacade
trong Bootstrapper của bạn. Bằng cách ghi đè số LoggerFacade
, bạn có thể chuyển vào một cá thể của bất kỳ Trình ghi nào bạn muốn với bất kỳ cấu hình nào cần thiết miễn là trình ghi nhật ký triển khai giao diện ILoggerFacade
.
tôi đã tìm thấy những điều sau đây để làm việc khá tốt để đăng nhập (Tôi đang sử dụng khối Logging Enterprise THƯ VIỆN, nhưng áp dụng một cái gì đó tương tự cho Log4Net nên thẳng về phía trước):
Tạo một boostrapper trong Shell của bạn:
-My Project
-Shell Module (add a reference to the Infrastructure project)
-Bootstrapper.cs
Tạo một adapter Logging trong dự án cơ sở hạ tầng của bạn, ví dụ:
-My Project
-Infrastructure Module
-Adapters
-Logging
-MyCustomLoggerAdapter.cs
-MyCustomLoggerAdapterExtendedAdapter.cs
-IFormalLogger.cs
Các MyCustomLoggerAdapt Lớp er sẽ được sử dụng để ghi đè thuộc tính 'LoggerFacade' trong Bootstrapper. Nó sẽ có một contstructor mặc định rằng tin tức tất cả mọi thứ lên.
Lưu ý: bằng cách ghi đè thuộc tính LoggerFacade
trong Bootstrapper, bạn đang cung cấp cơ chế ghi nhật ký cho Prism để sử dụng để ghi lại các thông điệp nội bộ của chính nó.Bạn có thể sử dụng trình ghi nhật ký này trong toàn bộ ứng dụng của mình hoặc bạn có thể mở rộng trình ghi nhật ký để có trình ghi nhật ký đầy đủ tính năng hơn. (Xem MyCustomLoggerAdapterExtendedAdapter
/IFormalLogger
)
public class MyCustomLoggerAdapter : ILoggerFacade
{
#region ILoggerFacade Members
/// <summary>
/// Logs an entry using the Enterprise Library logging.
/// For logging a Category.Exception type, it is preferred to use
/// the EnterpriseLibraryLoggerAdapter.Exception methods."
/// </summary>
public void Log(string message, Category category, Priority priority)
{
if(category == Category.Exception)
{
Exception(new Exception(message), ExceptionPolicies.Default);
return;
}
Logger.Write(message, category.ToString(), (int)priority);
}
#endregion
/// <summary>
/// Logs an entry using the Enterprise Library Logging.
/// </summary>
/// <param name="entry">the LogEntry object used to log the
/// entry with Enterprise Library.</param>
public void Log(LogEntry entry)
{
Logger.Write(entry);
}
// Other methods if needed, i.e., a default Exception logger.
public void Exception (Exception ex) { // do stuff }
}
Các MyCustomLoggerAdapterExtendedAdapter được dervied từ MyCustomLoggerAdapter và có thể cung cấp nhà xây dựng bổ sung cho một full-fledged logger hơn.
public class MyCustomLoggerAdapterExtendedAdapter : MyCustomLoggerAdapter, IFormalLogger
{
private readonly ILoggingPolicySection _config;
private LogEntry _infoPolicy;
private LogEntry _debugPolicy;
private LogEntry _warnPolicy;
private LogEntry _errorPolicy;
private LogEntry InfoLog
{
get
{
if(_infoPolicy == null)
{
LogEntry log = GetLogEntryByPolicyName(LogPolicies.Info);
_infoPolicy = log;
}
return _infoPolicy;
}
}
// removed backing code for brevity
private LogEntry DebugLog... WarnLog... ErrorLog
// ILoggingPolicySection is passed via constructor injection in the bootstrapper
// and is used to configure various logging policies.
public MyCustomLoggerAdapterExtendedAdapter (ILoggingPolicySection loggingPolicySection)
{
_config = loggingPolicySection;
}
#region IFormalLogger Members
/// <summary>
/// Info: informational statements concerning program state,
/// representing program events or behavior tracking.
/// </summary>
/// <param name="message"></param>
public void Info(string message)
{
InfoLog.Message = message;
InfoLog.ExtendedProperties.Clear();
base.Log(InfoLog);
}
/// <summary>
/// Debug: fine-grained statements concerning program state,
/// typically used for debugging.
/// </summary>
/// <param name="message"></param>
public void Debug(string message)
{
DebugLog.Message = message;
DebugLog.ExtendedProperties.Clear();
base.Log(DebugLog);
}
/// <summary>
/// Warn: statements that describe potentially harmful
/// events or states in the program.
/// </summary>
/// <param name="message"></param>
public void Warn(string message)
{
WarnLog.Message = message;
WarnLog.ExtendedProperties.Clear();
base.Log(WarnLog);
}
/// <summary>
/// Error: statements that describe non-fatal errors in the application;
/// sometimes used for handled exceptions. For more defined Exception
/// logging, use the Exception method in this class.
/// </summary>
/// <param name="message"></param>
public void Error(string message)
{
ErrorLog.Message = message;
ErrorLog.ExtendedProperties.Clear();
base.Log(ErrorLog);
}
/// <summary>
/// Logs an Exception using the Default EntLib Exception policy
/// as defined in the Exceptions.config file.
/// </summary>
/// <param name="ex"></param>
public void Exception(Exception ex)
{
base.Exception(ex, ExceptionPolicies.Default);
}
#endregion
/// <summary>
/// Creates a LogEntry object based on the policy name as
/// defined in the logging config file.
/// </summary>
/// <param name="policyName">name of the policy to get.</param>
/// <returns>a new LogEntry object.</returns>
private LogEntry GetLogEntryByPolicyName(string policyName)
{
if(!_config.Policies.Contains(policyName))
{
throw new ArgumentException(string.Format(
"The policy '{0}' does not exist in the LoggingPoliciesCollection",
policyName));
}
ILoggingPolicyElement policy = _config.Policies[policyName];
var log = new LogEntry();
log.Categories.Add(policy.Category);
log.Title = policy.Title;
log.EventId = policy.EventId;
log.Severity = policy.Severity;
log.Priority = (int)policy.Priority;
log.ExtendedProperties.Clear();
return log;
}
}
public interface IFormalLogger
{
void Info(string message);
void Debug(string message);
void Warn(string message);
void Error(string message);
void Exception(Exception ex);
}
Trong Bootstrapper:
public class MyProjectBootstrapper : UnityBootstrapper
{
protected override void ConfigureContainer()
{
// ... arbitrary stuff
// create constructor injection for the MyCustomLoggerAdapterExtendedAdapter
var logPolicyConfigSection = ConfigurationManager.GetSection(LogPolicies.CorporateLoggingConfiguration);
var injectedLogPolicy = new InjectionConstructor(logPolicyConfigSection as LoggingPolicySection);
// register the MyCustomLoggerAdapterExtendedAdapter
Container.RegisterType<IFormalLogger, MyCustomLoggerAdapterExtendedAdapter>(
new ContainerControlledLifetimeManager(), injectedLogPolicy);
}
private readonly MyCustomLoggerAdapter _logger = new MyCustomLoggerAdapter();
protected override ILoggerFacade LoggerFacade
{
get
{
return _logger;
}
}
}
Cuối cùng, để sử dụng hoặc logger, tất cả các bạn cần làm là thêm giao diện phù hợp với lớp constructor của bạn và UnityContainer sẽ bơm các logger cho bạn:
public partial class Shell : Window, IShellView
{
private readonly IFormalLogger _logger;
private readonly ILoggerFacade _loggerFacade;
public Shell(IFormalLogger logger, ILoggerFacade loggerFacade)
{
_logger = logger;
_loggerFacade = loggerFacade
_logger.Debug("Shell: Instantiating the .ctor.");
_loggerFacade.Log("My Message", Category.Debug, Priority.None);
InitializeComponent();
}
#region IShellView Members
public void ShowView()
{
_logger.Debug("Shell: Showing the Shell (ShowView).");
_loggerFacade.Log("Shell: Showing the Shell (ShowView).", Category.Debug, Priority.None);
this.Show();
}
#endregion
}
Tôi không nghĩ bạn cần một mô-đun riêng cho chính sách ghi nhật ký. Bằng cách thêm chính sách ghi vào mô-đun cơ sở hạ tầng của bạn, tất cả các mô-đun khác sẽ nhận được các tham chiếu bắt buộc (giả sử bạn thêm mô-đun cơ sở hạ tầng làm tham chiếu đến các mô-đun khác của bạn). Và bằng cách thêm bộ ghi vào Boostrapper của bạn, bạn có thể cho phép UnityContainer tiêm chính sách ghi nhật ký khi cần thiết.
Có một simple example of uisng Log4Net trên dự án đóng góp CompositeWPF trên CodePlex.
HTH's
Tôi thiếu đăng nhập phân cấp của log4net trong giải pháp này. Một cái gì đó mà tôi nghĩ là mất tích trong lăng kính quá. –