2017-02-22 8 views
0

Unityによって解決されるILogging依存関係を持つQCServiceLogクラスを持つ外部プロジェクトがあります。 しかし、あなたは、次の例に見ることができるようQCServiceLogはシングルトンクラスです:Dependency Injectionを使用したシングルトンクラスC#

private readonly ILogging _logging = null; 

private static QCServiceLog _instance = null; 
public static QCServiceLog Instance 
{ 
    get 
    { 
     return _instance; 
    } 
} 

public QCServiceLog(ILogging logging) 
{ 
    _logging = logging; 
    if (_instance == null) 
    { 
     _instance = this; 
    } 
} 

我々はそれを使用しようとしている、と私たちの溶液中で、私たちは次のように登録をした:

uc.RegisterType<ILogging, QCFileManager>(new ContainerControlledLifetimeManager()); 

しかしQCServiceLog以来コードがコンストラクタを決して経由しないと信じているシングルトンです。その後、_instanceはインスタンス化されません。私たちは、このやってそれを使用している :

QCServiceLog.Instance.Log(ex); 

はシングルトンが正しく実装ということですか? QCServiceLogの新しいを実行することは決してありません。

あなたはどう思いますか?外部プロジェクトを変更せずにできることはありますか? あなたが想像できる例外は:

オブジェクト参照がオブジェクトのインスタンスに設定されていません。

本当にありがとうございます。

答えて

1

シングルトンは正しく実装されていますか?

はい。しかし、静的インスタンスを取得する前に、最初にコンテナからインスタンス化する必要があります。あなたが最初の呼び出しまで

QCServiceLog.Instance.Log(ex); 

container.Resolve<QCServiceLog>(); 

(あなたがUnityとILoggingのインスタンスを登録していると仮定して)最初ので、言い換えれば

、あなたはこのラインを使用することはできません呼び出しはコンストラクターにヒットして_instance値を設定しません。

あなたはおそらく、それが必要とされる場所、それを直接注入するいずれかのほうが良いでしょう:

public class Foo(QCServiceLog log) 

または代わりに、あなたのDIコンテナを介して注入され、それを使用する前に、正しくそれを配線するロジックが含まれているラッパークラスを作成します。

いずれにしても、DIは主にのアプリケーションです。サードパーティのユーティリティは必ずしもDI環境に優しい方法ではないので、アプリケーションのコンテキスト内での使用にDIフレンドリーにするには、facadeまたはadapterを使用する必要があります。

1

あなたが提供したコードは、スレッドセーフではありません - Implementing the Singleton Pattern in C#ここを見て:

public QCServiceLog(ILogging logging) 
{ 
    _logging = logging; 
    if (_instance == null) 
    { 
     _instance = this; 
    } 
} 

もう一つの問題は、コンストラクタが隠されていないということです。したがって、IoCコンテナがクラスをシングルトンとして登録しても、new演算子を使用してコード内のどこでもこのクラスのインスタンスを構築できます。私は、この単なる(DI/IoCを使ってシングルトンとして登録されたが、手動でコードによって新しくされた)という理由で、私が働いていたアプリでメモリリークを発見した。

関連する問題