Jasmine
Jasmine

Reputation: 5326

Implement a class to find invocation time of methods in C#

I have a following situation

public interface IPay
{
  void IncreasePay();
  void DecreasePay();
}

public class PayCalculation: IPay
{
  private int Pay;
  public PayCalculation( int Pay)
  {
    Pay = Pay;
  }
  public void IncreasePay()
  {
    Pay++;
  }
  public void DescreasePay()
  {
    Pay--;
  }
}

Now, I want to implement a class to print how long each Increase &DecreasePay method takes to invocation in milliseconds which should fit with existing clients of IPay.

I was trying to work myself with Stopwatch, but do not know how to implement it in a class without affecting existing clients...

Could some one please help me with the code....

Upvotes: 0

Views: 62

Answers (2)

David
David

Reputation: 16277

You can use an aspect oriented approach, to implement your own attributes and add it to the method concerned.

[OnTransaction]
public void IncreasePay()
{
    Pay++;
}

[Serializable]
public class OnTransactionAttribute : OnMethodBoundaryAspect
{
    public override void OnEntry(MethodExecutionArgs args)
    {
        Log(DateTime.Now); // or other way such as StopWatch, whatever ...
    }
}

This way, you will get notified every time IncreasePay() is called. Similarly, you can create another attribute for DescreasePay() and do some logic therein. Here OnMethodBoundaryAspect is an attribute defined in PostSharp, which is free for this attribute class. You can of course do it yourself.

Note that you don't need to touch any internal logic of IncreasePay() or DescreasePay(), which is very useful and flexible.

Upvotes: 1

John Koerner
John Koerner

Reputation: 38079

You could create a wrapper class that also implements IPay and have it capture the amount of time it took.

public class PayWrapper : IPay
{
    private readonly IPay _wrapped;
    public PayWrapper(IPay wrapped)
    {
        if (wrapped == null) throw new ArgumentNullException(nameof(wrapped));
        _wrapped = wrapped;
    }

    public void DecreasePay()
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        _wrapped.DecreasePay();
        sw.Stop();
        Console.WriteLine(sw.Elapsed);

    }

    public void IncreasePay()
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();
        _wrapped.IncreasePay();
        sw.Stop();
        Console.WriteLine(sw.Elapsed);
    }
}

Then when a class gets an IPay, it can use the wrapper like this:

public class ConsumerOfPay
{
    private IPay _pay;
    public ConsumerOfPay(IPay pay)
    {
        _pay = new PayWrapper(pay);
    }
}

Upvotes: 0

Related Questions