publicclassUpdateUserRequest{ [AuthorizedUserPublisherRequired]publicintUserId{get;set;} [Required("Name is required")]publicstringName{get;set;} [ValidZipCodeRequired("Invalid zip code")]publicstringZipCode{get;set;}}publicinterfaceIUserService{voidUpdate(UpdateUserRequestrequest);}
There are validation frameworks out there that will do this, so what’s my beef? Well, first of all I want to inject the validators with dependencies to implement the juicier rules. And second, I’m treating validation as a core concern so I don’t want a dependency on a framework like Enterprise Library. I had several questions like:
How do I get dependencies into the validators?
How do I get ValidZipCodeRequired to fire with the value of the ZipCode property
This allows me to make a UnityValidatorFactory that can supply all my dependencies. Now how about this business of running the ValidZipCodeRequiredValidator with the value of the ZipCode property? For that I made a composite validator that loops through each property and runs the annotated validator against it’s property value.
Phew, we’re almost done. The only thing left is to apply this validator in configuration so I can keep the Unity reference out of my core domain. That looks like this:
Everybody’s favorite example for AOP is logging. There are a few reasons for that. First, it’s a great problem to solve with AOP and chances are it’s something everyone can relate to. Well, what happens when you actually use it for logging?
I can tell you what happened to me last week. Things were going great until it came time to port our credit card charging program from the stone age to .NET. It occurred to me that our fancy AOP logging would unknowingly log decrypted credit cards!
An obvious solution was to do a regex on log messages and mask credit card numbers – and that’s pretty much what we did, but I didn’t want to perform a regex on every message when I knew only a tiny percentage would contain sensitive data. The solution of course, was to fight fire with fire and use more AOP.
This way I could specifically mark an interface that I knew would accept sensitive data and apply an appropriate filter to it. The log filtering is implemented as a decorator to a log4net-like ILogger interface.
1234567891011121314151617181920212223
[TestFixture]publicclassLoggerWithFilterFixture{ [Test]publicvoidShould_apply_filter_to_message(){varlogger=newInterceptingLogger();varloggerWithFilter=newLoggerWithFilter(logger,newAppendBangToMessage());loggerWithFilter.Debug("This is a message");Assert.AreEqual("This is a message!",logger.LastMessage);}}publicclassAppendBangToMessage:ILogFilter{publicstringFilter(stringmessage){returnmessage+"!";}}
The decorator is then applied in the call handler by looking for custom attributes of type LogFilterAttribute like this:
Using a container for unit testing is a good way to insulate your tests from changes in object construction. Typically my first test will be something pretty boring just to get the process started. A few tests later, the real behavior comes out along with new dependencies. Rather than having to go back and add the dependencies to all the tests I’ve already written, I like to use a container to build up the object I’m testing.
To streamline this process, I thought it would be handy to use a container extension to auto generate mocks for any required interface that wasn’t explicitly registered. The best way I can explain this is with code, so here it is:
1234567891011121314151617181920
[SetUp]publicvoidSetUp(){container=newUnityContainer().AddNewExtension<AutoMockingContainerExtension>();}[Test]publicvoidShould_be_really_easy_to_test(){container.RegisterMock<IDependencyThatNeedsExplicitMocking>().Setup(d=>d.MyMethod(It.IsAny<int>())).Returns("I want to specify the return value");varservice=container.Resolve<ServiceWithThreeDependencies>();varresult=service.DoSomething();Assert.That(result,Is.EqualTo("I didn't have to mock the other 2 dependencies!"));}
It really reduces the noise level in tests and lets you focus on the interesting parts of your application. Here’s the code for the container extension:
I made a few tweaks to a captcha library I found here and basically wrapped their CaptchaImage object in a service interface to use in my application. Pretty easy stuff, but I didn’t get it right the first time.
Perhaps your nose can lead you in the right direction. The smell is hard to test, and it’s hard to test because it requires mocking the HttpContextBase. You might say “no problem, I can blast out a stub with Moq in no time” but you’re missing the real problem. That would be like taking aspirin for a brain tumor.
It’s not a tumor
The real problem is this class is violating the Single Responsibility Principle (SRP) by doing more than one thing. I don’t mean the two methods Render() and Verify(), those are a cohesive unit operating on the same data. The other thing is lifetime management. Look how simple the class gets when you invert control and take out the notion of lifetime management:
I read Domain Driven Design about a year and a half ago and when I got to the part about the specification pattern, I thought it was really cool and I couldn’t wait to try it out. Maybe the pattern gods were listening or maybe I was unknowingly using the secret. Either way, it was pretty much the next morning that I went to work and had the perfect project dropped in my lap.
Our phone system routes live phone calls to doctor’s offices and the project was to bill the doctor if the call met the following criteria:
Caller is a new patient (pressed “1” instead of “2” in response to a voice prompt)
A live call was connected for more than 20 seconds or message longer than 10 seconds was recorded.
The doctor has not already been billed for this caller.
The call is not from a known list of test numbers.
The application subscribes to an event stream of new call records and runs them through this composite specification to determine if the call is billable.
I have to admit that I was already an hour into Query Analyzer blasting through another monster stored procedure when I caught myself. Not just the criteria logic either, I mean bypassing all the event stream hooha and basically just writing the whole enchilada as one gnarly stored procedure that would run as a job. That was a close one!