3

ここで、時間間隔に基づいてメソッドを呼び出すクラスにタイマーが必要な状況があります。

通常のシナリオでは、タイマーをインスタンス化し、コンストラクター自体で構成します。しかし、依存性注入スタイルでやりたいです。コンストラクターでタイマーを渡すのは簡単ですが、メソッドをその OnTimeElapsed にバインドするには注意が必要です。クラスをインスタンス化するファクトリでこのタイマーを構成する必要がありますか? 依存性注入の原則に違反することなく、どうすれば先に進むことができますか。

ありがとう

編集1

わかりました、私が実際に聞きたかったことを言い換えさせてください。

  1. Miskoさんの投稿動画によると
  2. 彼の他の講演中 (フレームワークをテストしないでください: .net フレームワークはこちら)
  3. 彼のコード レビュー ガイドでは、コンストラクターでフィールドの割り当てを超えて行われたことはすべて悪いと見なされます。

依存性注入を達成するための私の主な目標は、特定の経過時間でメソッドが呼び出されたかどうかを単体テストする必要があることです。

だから私の質問は: OnTimerElapsed イベントをどこにバインドすればよいですか? ここで実際にタイマーをテストしようとしていますか? ここで迷子になりそう

親切に助けてください。

4

2 に答える 2

-2

依存性注入の初心者向けの回答を投稿します。

以前の問題のあるコードは次のとおりです。

public class MyClassInvoker:IDisposable
{
    readonly Timer _myTimer;
    readonly MyClass _myclass;
    public MyClassInvoker(Timer myTimer, MyClass myclass)
    {
        _myTimer = myTimer;
        _myclass = myclass;
        _myTimer.Interval = 3000;//configure Your timer here
        _myTimer.Elapsed +=new ElapsedEventHandler(PeriodicInvoker); 
    }

    public void Start()
    {
        _myTimer.Start();
    }

    public void Dispose()
    {
        _myTimer.Dispose();
    }

    void PeriodicInvoker(object sender, EventArgs e)
    {
        _myclass.DoSomePeriodicWork();
    }
}

コードを修正すると、次のようになります。

public class MyClassInvoker:IDisposable
{
    readonly Timer _myTimer;
    readonly MyClass _myclass;
    public MyClassInvoker(MyClass myclass)
    {
        _myTimer = new Timer();
        _myclass = myclass;

    }

    public void Start()
    {
        _myTimer.Interval = 3000;//configure Your timer here
        //add or remove any previous listeners 
        //here depending upon the business needs

        _myTimer.Elapsed += new ElapsedEventHandler(PeriodicInvoker); 
        _myTimer.Start();
    }

    public void Dispose()
    {
        _myTimer.Dispose();
    }

    void PeriodicInvoker(object sender, EventArgs e)
    {
        _myclass.DoSomePeriodicWork();
    }
}

問題について直感的に考えた後、分析を投稿しています。

  1. 私自身の質問に投稿されたリンクに従って、単純な割り当て以外にコンストラクターでこれ以上の作業を行わないでください。実際には、コンストラクターでイベント ハンドラーをバインドしていました。私がこのようにした場合、どのような影響があったかについて、今のところコメントすることはできません.
  2. テスト容易性を高めるために、前のコードで Timer オブジェクトを渡しました。

説明付きのソリューション

  1. 依存関係として Timer を渡すことで、.Net Timer BCL をモックするインターフェイスを提供して、Test をユニット化し、置換を提供しようとしました。現在、.Net には 3 種類のタイマーがあります。

    • System.Threading.Timer
    • System.Timers.Timer
    • System.Windows.Forms.Timer

    これらのタイマーはどれも同じインターフェイスを共有していないため、それらを依存関係として渡すのは無意味です。これは、修正したコードで修正しました。

  2. 論理的に考えると、MyClassInvoker クラスをインスタンス化した後に Start メソッドが呼び出されるので、そこにイベント バインディングを配置すると、非常に理にかなっています。

于 2013-09-01T02:32:51.410 に答える