2011-01-03 12 views
3

私はDependency Injectionに関するいくつかの記事を持っていますが、特に単体テストに関しては、その利点が分かります。ユニットは私と疎結合することができ、依存関係を嘲笑することができます。依存性注入:私はどこから始めなければならないのですか?

問題は - 私はちょうどどこから始めなければならないのですか?

私は持っている(この記事の目的のために多く編集された)コードの下でこのスニペットを検討してください。私は、メインフォームからPlcオブジェクトをインスタンス化し、Connectメソッドを介して通信モードで渡しています。

CommsChannelからPlcを単体テストに分離できないため、現状ではテストが難しくなります。 (できますか)

クラスはCommsChannelオブジェクトを使用するかどうかによって異なりますが、Plc内でこのチャネルを作成するためのモードでのみ渡しています。 Dependency Injectionを使うためには、既に作成されたCommsChannelを(おそらく 'ICommsChannel'インターフェースを介して)Connectメソッドに渡すか、Plcコンストラクタ経由で渡すべきです。そうですか?

しかし、それは最初に私のメインフォームにCommsChannelを作成することを意味し、これはどちらかと思われません。すべてが始まるメインフォームの基本レイヤーにすべてが戻ってくるように感じるからです。どういうわけか、私はパズルの重要な部分が欠けているように感じます。

どこから始めますか? のインスタンスをのどこかに作成する必要がありますが、どこにあるべきかを理解するのは苦労しています。

public class Plc() 
{ 
    public bool Connect(CommsMode commsMode) 
    { 
     bool success = false; 

     // Create new comms channel. 
     this._commsChannel = this.GetCommsChannel(commsMode); 

     // Attempt connection 
     success = this._commsChannel.Connect(); 

     return this._connected; 
    } 

    private CommsChannel GetCommsChannel(CommsMode mode) 
    { 
     CommsChannel channel; 

     switch (mode) 
     { 
      case CommsMode.RS232: 
       channel = new SerialCommsChannel(
        SerialCommsSettings.Default.ComPort, 
        SerialCommsSettings.Default.BaudRate, 
        SerialCommsSettings.Default.DataBits, 
        SerialCommsSettings.Default.Parity, 
        SerialCommsSettings.Default.StopBits); 
       break; 

      case CommsMode.Tcp: 
       channel = new TcpCommsChannel(
        TCPCommsSettings.Default.IP_Address, 
        TCPCommsSettings.Default.Port); 
       break; 

      default: 
       // Throw unknown comms channel exception. 
     } 

     return channel; 
    } 
} 
+0

関連:http://stackoverflow.com/questions/4570750/dependency-injection-turtles-all-the-way-down/4570814#4570814 –

+0

依存性注入タグのイントロ/よくある質問はhttp: /stackoverflow.com/tags/dependency-injection/info –

+0

アプリケーションを作成する場所:http:// stackoverflow。com/questions/1410719/design-where-should-using-objects-be-registered-when-using-windsor/1410738#1410738 –

答えて

1

このような幅広い質問にはお答えできませんが、接続オブジェクトを作成する場所/作成者の具体的な質問は簡単です。

接続オブジェクトの作成方法とモードの代わりに、あるいはその代わりに接続オブジェクトを作成する方法を知っているファクトリオブジェクトを渡すことができます。このようにして、異なる(例えばモック)接続を作成する場合は、別のファクトリオブジェクトを渡すだけで、別のファクトリオブジェクトが作成されます。

これは役に立ちますか、または本当の質問を逃しましたか?

+0

ありがとう、それは助けになります。 OK、CommsChannelFactory ... ICommsChannelFactoryインターフェイスを使用するファクトリを持っていて、ユニットテスト時にこのインターフェイスでMockCommsChannelFactoryを作成すると、ダミーのICommsChannelオブジェクトが返されますか? (私はここで正しい行にいるのですか?) – Andy

+0

それは私にとって正しい行のように聞こえる。オブジェクト/実装がどのようにプラグイン可能であるかが分かりますが、バランスを取ってみると、インタフェースやインジェクションの指数関数的な爆発で終わることになり、システムを理解するのが難しくなります。 – DaveC

+0

「理解が難しい」私はこの必要はありません:)この例は、懸念を分けてテストを簡単にするためのインターフェイスの自然な場所のようですが、私はあなたの要点を取ります。 – Andy

0

私は何をしますか?

従属性注射は、S.O.L.I.Dの原則を適用するとすぐに実行されるものです。そのため、行動に直接飛び込む代わりに、この優れたpdfを読んでください。

http://www.lostechies.com/blogs/chad_myers/archive/2008/03/07/pablo-s-topic-of-the-month-march-solid-principles.aspx

そして、チェックアウト。例については

http://structuremap.net/structuremap/

これは私の人生の中で最高の乗り物でした。それはあなたにとって平等な体験であることを願っています。

関連する問題