2017-05-08 3 views
0

私は依存性注入を学習しています。多くの投稿を読んで本を使うと、下のコードは私が読んだことと本の例に基づいています。このコンソールプログラムは動作します。 DIの詳細と単体テストで使用する前に、正しく理解しているかどうか、正しくコーディングしているかどうかを確認したいと思います。この依存関係注入の例と説明は正しいですか?

メイン

Sub Main() 

    Dim myWriter As IMessageWriter     'myWriter must be same type as ConsoleMessageWriter, next line. That is INTERFACE type IMessageWriter 
    myWriter = New ConsoleMessageWriter()   'myWriter INSTANCE is required to construct MyConsoleWriter INSTANCE below 

    Dim myConsoleWriter As ConsoleWriter   'myConsoleWriter must be same type as ConsoleWriter, next line. That is CLASS type ConsoleWriter 
    myConsoleWriter = New ConsoleWriter(myWriter) 'myConsoleWriter INSTANCE contructed w/ myWriter INSTANCE. myConsoleWriter exposes ConsoleWrite 

    myConsoleWriter.ConsoleWrite("Hello DI world.", True) 'INSTANCE myConsoleWriter's ConsoleWrite method uses INSTANCE MyWriter's Write method 
End Sub 

ConsoleWriter

Public Class ConsoleWriter 

    Private ReadOnly writer As IMessageWriter 

    Public Sub New(writer As IMessageWriter) 
    If writer Is Nothing Then 
     Throw New ArgumentNullException("writer") 
    End If 
    Me.writer = writer 
    End Sub  

    Public Sub ConsoleWrite(message As String, pause As Boolean) 
    Me.writer.Write(message, pause) 
    End Sub 
End Class 

ConsoleMessageWriter

Public Class ConsoleMessageWriter 
    Implements IMessageWriter 

    Public Sub Write(message As String, pause As Boolean) Implements IMessageWriter.Write 

    If pause Then 
     Console.WriteLine(message) 
     Console.WriteLine("<press any key to continue>") 
     Console.ReadKey() 
    Else 
     Console.WriteLine(message) 
    End If 

    End Sub 
End Class 

IMessageWriter

Public Interface IMessageWriter 
    Sub Write(message As String, pause As Boolean) 
End Interface 

上記のコードにコメントを追加して、なぜ各ステップが取られたかを思い出させ、下の図はこの方法論を理解しようとするために作成した画像です。 enter image description here

私の質問は簡単です。コードに何か問題はありますか?コード内のコメント?グラフィック?コードに関しては、いくつかの行を組み合わせることができると私は理解していますが、私は基本的な理解を高めるためにそれらを壊しました。

ありがとうございました。

答えて

1

あなたのコードは依存関係注入の概念を正しく示しており、図はmyConsoleWriter.ConsoleWrite呼び出しの実行方法を正しく示しています。私が変える唯一の事は、あなたのコメントはmyWriter must be same type as ConsoleMessageWriter, next line. That is INTERFACE type IMessageWriterと言っています。それは本当に正確ではありません。 myWriterConsoleMessageWriterの型である必要はなく、IMessageWriterを実装する型である必要があります。したがって、Public Class OtherConsoleMessageWriter Implements IMessageWriterがある場合は、もOtherConsoleMessageWriterとなります。

言われていること、あなたがあなたのMain方法が書かれている方法はConsoleWriterへの依存性を注入するその概念を実証するだけであることを理解し、それが実際のプログラムでは、あなたがmyWriter = New ConsoleMessageWriter()を行うにはしたくないことを確認してください。あなたが依存性注入を学んでいるので、私はあなたがまだDIコンテナのトピックに慣れていないと仮定します。要点は、依存関係を明示的に作成したくないということです。従属関係を特定のタイプ(場合によってはConsoleMessageWriter)にハードコーディングするためです。 DIコンテナを使用すると、コンテナを構成して、各インターフェイスにどのような具体的な型を返すかを指定できるようになります。そして、DIコンテナにすべての依存関係を作成させることができます。

+0

Thx! myWriterが次の行のConsoleMessageWriterと同じインターフェースを実装する必要があるという最初のコメントを変更しています。これはINTERFACE型IMessageWriter'です。それはより正確ですか?そして、はい、私はDI容器を使用する必要があり、それに取り組んでいることを実感します。 ICommandを実装する個々のクラスの代わりにICommandを実装するRelayCommandクラスと呼ばれるものを使用するのと同様の方法でDIコンテナを表示するのは正しいでしょうか? – Alan

+0

「myWriterはIMessageWriterインターフェースを実装する必要があります」というコメントを変更し、「ConsoleMessageWriter」についてのコメントには何も言いません。依存関係注入のすべてはインターフェースにしか関係しないので、 'ConsoleWriter'の中には' ConsoleMessageWriter'クラスが存在することを知るべきではありません。 'ConsoleWriter'は、' IMessageWriter'を実装する依存関係が与えられていることだけを気にします。 –

+0

DIコンテナは 'RelayCommand'とは異なり、無関係の2つの目的を満たします。DIコンテナは次のように動作します。プログラムの先頭、コンポジションルートのどこかに、クラスと依存関係のすべてを結び付けます。ですから、 'ConsoleWriter'オブジェクトを作成するときには、' IMessageWriter'を実装するオブジェクトを渡す必要があります。あなたの例では、 '新しいConsoleMessageWriter'を作成します。 DIコンテナを使用すると、コンテナに 'IMessageWriter'を実装するオブジェクトを作成し、それを依存関係として渡すように指示します。そうすれば、 'ConsoleMessageWriter'はハードコーディングされません。 –

関連する問題