2011-01-24 12 views
0

私のアプリケーション(MVC3 Webアプリケーション)にlog4netを使ってCastle Logging機能を使用しています。しかし、ILoggerインターフェイスを直接使用するのではなく、具体的な実装Log4NetAuditor(下のコードを参照)を使用して別のインターフェイス(IAuditor)を作成して抽象化しました。log4net loggerの名前を設定する

ILoggerのポイントは基本的なロギングの実装を抽象化することなので、なぜこれをやったのか聞いてみることができます。私はすべてのインフラストラクチャの懸念を抽象化するという原則を厳守したために行ってきました。 MyProject.Infrastructure.Log4NetAuditor:すべてのロガーは、同じ名前が付けられてい除き

は今、これはうまく動作します

2011-01-24 13:26:11,746 [11] DEBUG MyProject.Infrastructure.Log4NetAuditor [] - Attempting login... 
2011-01-24 13:26:11,845 [11] DEBUG MyProject.Infrastructure.Log4NetAuditor [] - Authentication result is Authenticated 

IAuditorは抽象クラスであるAuditableComponentのプロパティとして公開されてからのすべてのコンポーネントログを取得する必要があります。

public abstract class AuditableComponent 
{ 
    private IAuditor _auditor = NullAuditor.Instance; 

    public IAuditor Auditor 
    { 
     get { return _auditor; } 
     set { _auditor = value; } 
    } 

    //.... 
} 

Log4NetAuditorクラスは次のようになります。

public class Log4NetAuditor : IAuditor 
{ 
    private ILogger _logger = NullLogger.Instance; 

    public ILogger Logger 
    { 
     get { return _logger; } 
     set { _logger = value; } 
    } 

    public void Trace(string message) 
    { 
     _logger.Debug(message); 
    } 
} 

すべてのログ・ステートメントは、同じロガー名を持っている理由、それは明らかだ:ILoggerですがLog4NetAuditorクラスに注入されます。

どのようにして、ロガーの名前がAuditableComponentを拡張するクラスの名前に対応するようにすることができますか?

+0

なぜLoggingFacilityを使用していないのですか?それは機能を提供しますOOTB –

+0

こんにちはKrzystof、私はLoggingFacilityを使用しています。しかし、私はクライアントアプリケーションでILogger(つまりWindsor)への参照を望んでいません。それでIAuditorの抽象化が行われます。 –

+0

は、施設の仕組みを見て、それを複製することができます。それはOSSのメイトです - あなたが好きなようにそのコードを使用して修正することができます:) –

答えて

1

私はあなたと同じことをしましたが、ロガーをインスタンス化する静的なLogManagerクラスも含めました。私は自分のコンストラクタをLoggerクラス(監査者クラス)の内部に作成し、直接作成できないようにしました。つまり、外部エンティティはLogManagerクラスを通じて参照を取得する必要があります。

public static class LogManager 
{ 
    public static readonly ILogger Log = CreateLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

    /// <summary> 
    /// Creates the logger for the specified type. 
    /// </summary> 
    /// <param name="loggerType">Type of the logger.</param> 
    /// <returns></returns> 
    public static Logger CreateLogger(Type loggerType) 
    { 
     return new Logger(loggerType); 
    } 

    /// <summary> 
    /// Creates the logger for the specified name. 
    /// </summary> 
    /// <param name="loggerName">Name of the logger.</param> 
    /// <returns></returns> 
    public static Logger CreateLogger(string loggerName) 
    { 
     return new Logger(loggerName); 
    } 
} 

これらのタイプでは、独自のタイプを作成メソッドに渡してAuditorをインスタンス化できます。

UPDATE -

私も、このコードに依存性を注入するユニティ容器を使用しました。関連ビットはInjectionFactoryです。いくつかの条件に基づいてタイプを注入する静的メソッドをローカルで指定することができます。

DependencyInjection.Container.RegisterType<IFormatter>(
    new ContainerControlledLifetimeManager(), 
    new InjectionFactory(c => CreateFormatter(filename, outputType))); 

... 

     private static IFormatter CreateFormatter(string filename, OutputType outputType) 
     { 
      TextWriter textWriter = (filename.Length > 0) ? new StreamWriter(filename) : new StreamWriter(Console.OpenStandardOutput()); 
      var formatter = (outputType == OutputType.Xml) ? (IFormatter)new XmlFormatter(textWriter) : new CsvFormatter(textWriter); 

      return formatter; 
     } 

... 
// Calling it 
using (var formatter = DependencyInjection.Container.Resolve<IFormatter>()) 
{ 
    if (timeLimit <= 1000) retval = OutputResults(results, formatter, msxQuery); 
    else TimedOutputResults(results, formatter, msxQuery, timeLimit, OutputResults); 
} 

まあ、それは少なくとも私のためです!

+0

答えをありがとう。それは役に立ちます。しかし、私はこのアプローチを城のコンテナとどのように組み合わせるのか見て少し苦労しています。現時点では、IAuditorはAuditableComponentのプロパティを介して注入されます。私はあなたのLogManagerを呼び出すためにファクトリメソッドを使用する方法を考えることができません...私はオフトラックですか? –

+0

Unity Containerを使用しています。上記のコードを更新し、Unityコードを正しく挿入するようにします。私はキャッスルウィンザーを使用して停止し、この機能を持って覚えていないことができます。しかし、あなたはまだウィンザーを使ってそれを行うことができるかもしれません。 – phillip

+0

ありがとうございます。あなたのアプローチは良いですが、私は自分のソリューションにそれをどのように適用できるのか分かりません。それは、あなたに私にいくつかのアイデアを与えてくれました。ありがとうございました。 –

関連する問題