Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C#, how do I keep certain method calls out of the codebase entirely?

Tags:

methods

c#

I'm trying to get rid of all DateTime.Now method calls and replace them with my own GetNow() method, which may sometimes return a fixed date for testing purposes.

How can I enforce that no one adds a DateTime.Now call in the future? Can I use NDepend or StyleCop to check this on my continuous integration server?

like image 858
nganju Avatar asked Feb 23 '11 17:02

nganju


2 Answers

With NDepend it is very easy to write this rule:

// <Name>Forbid DateTime.Now, use xxx.GetNow() instead</Name>
WARN IF Count > 0 IN 
SELECT METHODS WHERE 
IsDirectlyUsing "OPTIONAL:System.DateTime.get_Now()"

Notice:

  • The prefix WARN IF Count > 0 IN that transforms the CQL query into a rule
  • The way the property is referenced through the string System.DateTime.get_Now()
  • The prefix OPTIONAL that means "Don't emit a compilation error if the property get_Now is not found". This makes sense since if your code doesn't use anymore get_Now(), it is not anymore referenced from NDepend analysis.

Also, to generate the original query...

SELECT METHODS WHERE 
IsDirectlyUsing "OPTIONAL:System.DateTime.get_Now()"

...just right-click DateTime.get_Now() and choose Select methods ... that are directly using me

enter image description here

like image 150
Patrick from NDepend team Avatar answered Sep 18 '22 13:09

Patrick from NDepend team


Firstly, DateTime.Now is a property.
That means you don't need to put parenthesis after call.

Secondly, if by testing purposes you mean a framework like NUnit, you might want to check out Microsoft Moles which allows you to substitute any static method call with your own custom implementation while testing. Heck, it's cool:

[Test]
[ExpectedException (typeof (Y2KBugException))]
public void TestY2KBug ()
{
    MDateTime.NowGet = () => new DateTime (2001, 1, 1);
    Bomb.DetonateIfY2K ();
}


public static class Bomb {
    public static void DetonateIfY2K ()
    {
        if (DateTime.Now == new DateTime (2001, 1, 1))
            throw new Y2KBugException (); // take cover!
    }
}
like image 33
Dan Abramov Avatar answered Sep 20 '22 13:09

Dan Abramov