1

メソッドを使用して例外を処理します。内部的にはデータベースに書き込みますが、Web にリリースすると、ソース コードにはデータベースへの書き込みに必要な接続文字列が含まれません。代わりに、ログ ファイルに書き込む必要があります。

Foo.Private.dll が存在しない場合はログへの書き込みに対応できますが、存在する場合はデータベースに書き込みますか?

//In Foo.Public.dll assembly
public class SimpleLogWriter
{
    public virtual void LogError(Exception ex)
    {
        //Write to log file.
    }
}

...

//In Foo.Private.dll assembly
public class ExtendedLogWriter : SimpleLogWriter
{
    public override void LogError(Exception ex)
    {
        //Write to database
    }
}

両方のログ クラスに共有インターフェイスを実装し (拡張およびオーバーライドする代わりに)、それをレンダリングするファクトリ メソッドを作成することを検討しましたが、アセンブリの存在を検証する方法や、参照を追加せずにその型を使用する方法がわかりません。最終プロジェクトには循環参照があります。

4

4 に答える 4

1

これを実現する方法はいくつか考えられます。

固く結ばれた

リフレクションを使用して、DLL の存在を検出します。存在する場合は、適切なクラスをロードし、追加の呼び出しを行います。

これを行うには、Assembly.LoadFileAssembly.GetType(string)、およびActivator.CreateInstance(type)を使用します。新しいインスタンスを抽象ベース ロガー タイプ/インターフェイスにキャストします。

これは多かれ少なかれあなたが説明していたことです。ただし、これはあまり柔軟ではなく、適切な代替手段があるため、お勧めしません。

疎結合

インターフェイスまたは抽象ロガー クラスを作成し、依存性注入 (制御の反転)を使用して、ロギングを行う必要があるコンポーネントにロガーを注入します。必要に応じて、依存性注入ライブラリを使用して、疎結合の方法で必要な実装を指定できます。追加の DLL (存在する場合) から依存関係を読み込むように DI ライブラリを構成します。

Castle.Windsor には疎結合のログ インターフェイス (ログ機能) があり、2 番目のオプションを調べることができます。

これらの間にも一種のスペクトルがあります。

これは、ロガーを依存関係として注入する要点です (ただし、この例ではライブラリを使用していません)。

using System;
using System.IO;

public interface ILogger
{
    void WriteDebug(string debug);
    void WriteInfo(string info);
    void WriteError(string error);
}

public class NullLogger : ILogger
{
    private static ILogger instance = new NullLogger();

    // This singleton pattern is just here for convenience.
    // We do this because pattern has you using null loggers constantly.
    // If you use dependency injection elsewhere,
    // try to avoid the temptation of implementing more singletons :)
    public static ILogger Instance
    {
        get { return instance; }
    }

    public void WriteDebug(string debug) { }
    public void WriteInfo(string info) { }
    public void WriteError(string error) { }
}

public class FileLogger : ILogger, IDisposable
{
    private StreamWriter fileWriter;

    public FileLogger(string filename)
    {
        this.fileWriter = File.CreateText(filename);
    }

    public void Dispose()
    {
        if (fileWriter != null)
            fileWriter.Dispose();
    }

    public void WriteDebug(string debug)
    {
        fileWriter.WriteLine("Debug - {0}", debug);
    }

    // WriteInfo, etc
}

public class SomeBusinessLogic
{
    private ILogger logger = NullLogger.Instance;

    public SomeBusinessLogic()
    {
    }

    public void DoSomething()
    {
        logger.WriteInfo("some info to put in the log");
    }

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

public class Program
{
    static void Main(string[] args)
    {
        // You're free to use a dependency injection library for this,
        // or simply check for a DLL via reflections and load a logger from there
        using (var logger = new FileLogger("logfile.txt"))
        {
            var someBusinessLogic = new SomeBusinessLogic()
            {
                // The component won't know which logger it is using - it just uses it
                Logger = logger,
            };

            someBusinessLogic.DoSomething();
        }
    }
}
于 2011-06-01T06:26:31.657 に答える
1

これは、.NET 4.0 で利用可能なManaged Extensibility Framework (MEF)の潜在的なユース ケースのように思えます。

于 2011-06-01T06:27:49.743 に答える
0

これは、ログ ライターをどのように作成するかだけの問題のように思えます。DLL が存在するかどうかに基づいて実行しようとするのではなく、クラスをインスタンス化して構成全体の一部にすることができます。ユーザー (つまり、インストールする人) に、必要ExtendedLogWriterかどうか、Foo.Private.dll を持っているかどうか、およびSimpleLogWriterそれ以外を指定させます。これを簡単にするさまざまな IoC コンテナがあります。

于 2011-06-01T06:24:51.467 に答える
0

これは、制御の反転を使用することで解決できます。

LogError(Exception) メソッドを持つインターフェイス IErrorLogger は、次のように実装されます。

  • DbErrorLogger
  • FileErrorLogger

ASP.NET 4.0 にはWeb.debug.configWeb.release.configがあり、デバッグおよび Web へのリリース シナリオ用に Web アプリケーションを構成できるため、Castle Windsor のような制御 API の反転を使用して、IErrorLogger コンポーネントを別の方法で構成します。

結局のところ、コンパイルをリリースに変更すると、FileErrorLogger は IErrorLogger の実装になります。

詳細については、次のリンクを参照してください: http://docs.castleproject.org/Windsor.MainPage.ashx

于 2011-06-01T06:37:46.947 に答える