2017-05-05 7 views
-1

すべてのDIフレームワークがアプリケーション起動前にすべての依存関係をランタイムでチェックするのはなぜですか?コンパイル時にそれをチェックしないと、そのメリットは何ですか?コンパイル時の依存性注入

デプロイされたアプリケーションの依存関係を変更することはできますか? たとえば、アプリケーションの起動時に電子メールで通知を送信しますが、その後アプリケーションを停止せずにSMS経由で送信するように変更できますか?

+0

あなたはDIフレームワークを使用する際にポイントを逃したようです...コンパイル時にそれを行うと、依存関係をDI配線ではなくハード配線するだけです... – Milney

+1

OK、依存関係を変更できます既に展開されているアプリケーションでは? – Romper

+0

これは一つの点です。また、実行時に知られている他の情報に基づいて、さまざまな実装を条件付きで登録することもできます... – Milney

答えて

2

DIコンテナ定義は、リフレクションを使用して動作します。つまり、実行時メタデータを意味します。コンパイル時にすべてをチェックするには、DIコンテナを使用するのではなく、依存関係を手作業で結ぶ必要があります。手でDIを適用することは、Pure DIと呼ばれる一般的な方法です。

しかし、その後、アプリケーションを停止せずにsmsを送信するように変更できますか?

実行している間も構成の変更に対応する必要があるようです。これを達成するための一般的なパターンがあります。通常、アプリケーションのコンポーネントオブジェクトグラフ(依存関係を持つ動作を含むクラスの連鎖)を一度定義します。要求ごとにそのようなグラフを作成するかもしれませんが、グラフの形は後で変わるべきではありません。代わりに、プロキシやコンポジットなどのパターンを使用します。次のインターフェイスと実装を考慮すると例えば:

class ConfigBasedNotificationSenderProxy : INotificationSender 
{ 
    private readonly INotificationSender mail; 
    private readonly INotificationSender sms; 

    public ConfigBasedNotificationSenderProxy(
     INotificationSender mail, INotificationSender sms) 
    { 
     this.mail = mail; 
     this.sms = sms; 
    } 

    public void Send(string message) 
    { 
     bool sendThroughMail = ReadFromConfgWhereToSendTo(); 
     var sender = sendThroughMail ? this.mail : this.sms; 
     sender.Send(message); 
    } 
} 

あなたはアプリケーションの起動時に、次のオブジェクトグラフ構築することができます:あなたは

var sender = new ConfigBasedNotificationSenderProxy(
    new MailNotificationSender(...) 
    new SmsNotificationSender(...)); 

interface INotificationSender 
{ 
    void Send(string message); 
} 

class MailNotificationSender : INotificationSender { ... } 

class SmsNotificationSender : INotificationSender { ... } 

我々は次のようにプロキシを定義することができますこれをDIコンテナでワイヤリングすることもできますし、手動で行うこともできます(純粋なDI)。ただし、ここでは、アプリケーションが実行時にどのように動作するかを変更する必要がある場合でも、アプリケーションを再配線する必要はありません。プロキシ実装を使用して、アプリケーションのオブジェクトグラフを通るコールグラフを変更できる必要があります。

+0

実行時のアプリケーション動作の変更に関する情報で更新されました。 – Steven