Ben gibi cephe günlüğü kullanmak için kullanılan Common.Logging (hatta kendi gizlemek için CuttingEdge.Logging kütüphane), ancak günümüzde kullandığım Bağımlılık Enjeksiyon kalıbı ve bu benim kendi (basit) soyutlama arkasında gizlemek loggers beni izin verdiğini hem yapıştığı Bağımlılık Ters Çevirme İlkesi ve Arayüz Ayrım İlkesi(ISP) bir üyeye sahip olduğu ve arayüz uygulamam tarafından tanımlandığı için; harici bir kitaplık değil. Uygulamanızın temel bölümlerinin harici kitaplıkların varlığıyla ilgili sahip olduğu bilgileri en aza indirgemek daha iyidir; günlük kitaplığınızı değiştirmek gibi bir niyetiniz olmasa bile. Harici kitaplığa olan sıkı bağımlılık, kodunuzu test etmeyi zorlaştırır ve uygulamanızı, asla uygulamanız için özel olarak tasarlanmamış bir API ile karmaşık hale getirir.
Uygulamalarımda soyutlama genellikle böyle görünüyor:
public interface ILogger
{
void Log(LogEntry entry);
}
public enum LoggingEventType { Debug, Information, Warning, Error, Fatal };
public class LogEntry
{
public readonly LoggingEventType Severity;
public readonly string Message;
public readonly Exception Exception;
public LogEntry(LoggingEventType severity, string message, Exception exception = null)
{
if (message == null) throw new ArgumentNullException("message");
if (message == string.Empty) throw new ArgumentException("empty", "message");
this.Severity = severity;
this.Message = message;
this.Exception = exception;
}
}
İsteğe bağlı olarak, bu soyutlama bazı basit genişletme yöntemleriyle genişletilebilir (arayüzün dar kalmasına ve ISP'ye bağlı kalmasına izin verir). Bu, bu arayüzün tüketicileri için kodu çok daha basit hale getirir:
public static class LoggerExtensions
{
public static void Log(this ILogger logger, string message) {
logger.Log(new LogEntry(LoggingEventType.Information, message));
}
public static void Log(this ILogger logger, Exception exception) {
logger.Log(new LogEntry(LoggingEventType.Error, exception.Message, exception));
}
}
Arabirim yalnızca tek bir yöntem içerdiğinden , log4net'e , Serilog , Microsoft.Extensions.Logging , NLog veya diğer herhangi bir günlük kitaplığına proxy oluşturan bir ILogger
uygulamayı kolayca oluşturabilir ve DI kapsayıcınızı, içinde a bulunan sınıflara enjekte edecek şekilde yapılandırabilirsiniz. yapıcı.ILogger
Tek bir yöntemle bir arabirimin üstünde statik uzantı yöntemlerine sahip olmanın, birçok üyeli bir arabirime sahip olmaktan oldukça farklı olduğunu unutmayın. Uzantı yöntemleri, bir LogEntry
mesaj oluşturan ve bunu ILogger
arayüzdeki tek yöntemden geçiren yardımcı yöntemlerdir . Uzantı yöntemleri, tüketicinin kodunun bir parçası haline gelir; soyutlamanın bir parçası değil. Bu, yalnızca uzantı yöntemlerinin soyutlamayı, uzantı yöntemlerini ve genişletme yöntemlerini değiştirmeye gerek kalmadan gelişmesine izin vermez.LogEntry
yapıcı, günlükçü soyutlaması kullanıldığında, bu günlükçü stubbe edilmiş / alay edilmiş olsa bile her zaman çalıştırılır. Bu, bir test paketinde çalışırken kaydediciye yapılan çağrıların doğruluğu hakkında daha fazla kesinlik sağlar. Tek üyeli arayüz testi çok daha kolay hale getirir; Çok sayıda üyeyle bir soyutlamaya sahip olmak, uygulamalar (taklitler, bağdaştırıcılar ve dekoratörler gibi) oluşturmayı zorlaştırır.
Bunu yaptığınızda, günlüğe kaydetme cephelerinin (veya başka herhangi bir kütüphanenin) sunabileceği bazı statik soyutlamalara neredeyse hiç gerek kalmaz.