Just trying to make sense of things...

Rhino Mock 3.5 Release Candidate - I Got To Help!

Monday, 30 June 2008 02:22 by jordan.terrell

Rhino Mocks 3.5 just went to release candidate.  Probably the biggest change is the new Arrange-Act-Assert (or AAA) syntax.  This now allows you to use a nearly identical approach to Moq's API.  What I like about Rhino Mocks is the fact that it uses extension methods, so you don't have to access an "Object" property to get the real mocked object.

But what is even cooler about this release, at least for me, is that I got to help with it!  I was migrating a project over to Rhino Mocks 3.5 beta, specifically because I wanted to make use of the new AAA syntax to simplify our tests, and during that process I found a pretty big bug - ordered expectations did not work with the new syntax.

To make the problem summary short, when you used the Expect() extension method, it put your mock object in Record mode, recorded the expectation, and then immediately put the mock object back in Replay mode.  Two problems with this: First, it assumed you were in Replay mode to begin with (Ayende noticed/fixed that); Second, switching back to Replay mode originally would ensure that you could not do so within the context of an Ordered() scope.  This was, I assume more to encourage proper use of the API than a real design/implementation constraint.  With the fix that I made in place, IF you were in Replay mode when you call the Expect() extension method, it now skips the check to see if you are in an Ordered() scope.  However, using the previously existing MockRepository.Replay() method still behaves the way it did before - it will throw an exception if you try to call it within an Ordered() scope.  The reason we can make an exception for the extension method is because it is an atomic action: if you were in Replay mode already, you will just be adding an expectation; you'll still end up in Replay mode.  If you were not in Replay mode, it will not try to place you in replay mode.  The API with the fix in place still protects the invariant disallowing you to enter an Ordered() scope in Record mode and switching into Replay mode before exiting the Ordered() scope.

If you want to look at my fix, it's revision 1482 in the Rhino Mocks Subversion repository.  Not a rocket science-like fix, but it's still cool that I got to contribute, and that Ayende choose to recognize my contribution when announcing the Release Candidate (thanks Ayende!).

You can bet I will be updating my project to use the Release Candidate later today...

Categories:   .NET | Programming
Actions:   E-mail | | Permalink | Comments (1) | Comment RSSRSS comment feed

Apress Books 45+% Off!!!

Tuesday, 24 June 2008 14:26 by jordan.terrell

Anyone who knows me well knows that I'm a huge book reader (mostly technical in content).  I love to learn new things, and books present, at least to me, and ideal package.  Having said that, you can imagine I get pretty excited when there is a book sale; especially when the discount exceeds 30%.

I'm normally a Borders fan, however Bookpool is having a sale on many new Apress books, all discounted at 45% or more.

I personally recommend the book entitled "Pro C# 2008 and the .NET 3.5 Platform (4th Edition)" by Andrew Troelsen.  The very first edition (based on .NET 1.0 beta) introduced me to .NET.  Since then, this book has grown to include new framework and language features all the way up to .NET 3.5 and C# 3.0 (2008).


Tags:   ,
Categories:   .NET | Programming
Actions:   E-mail | | Permalink | Comments (1) | Comment RSSRSS comment feed

IEnlistmentNotification: Implementation Nuances

Friday, 20 June 2008 11:15 by jordan.terrell

I am a big fan of System.Transactions.  It is by far one of the coolest additions to the .NET framework.  It was what introduced me to the power of ThreadStatic variables (use with caution).

Since being introduced to System.Transactions, I've been using it to create transactional business objects (volatile resources in System.Transactions lingo).  This has worked very well for me, however, I recently (read: in the past two weeks) discovered some nuances in implementing IEnlistmentNotification that might not be readily obvious or documented (as far as I could tell).

Nuance 1: Do not throw exceptions from the Prepare(PreparingEnlistment pe) method

If you need to indicate that your resource cannot prepare for the transaction to complete, you must call the ForceRollback(...) method on the PreparingEnlistment object passed into your implementation of Prepare().  If you want to include additional information on why your resource was unable to prepare for the transaction to complete, there is an overload of ForceRollback() that accepts an object that derives from System.Exception.  Once all resources have rolled back, the System.Transactions infrastructure will throw a TransactionAbortedException.  Any custom exception that you've provided to the ForceRollback() method will surface as the InnerException on the TransactionAbortedException thrown by the System.Transactions infrastructure.

You should NOT throw an exception from Prepare(), and you should wrap all code within the Prepare() method with a try/catch block - the catch block should catch all exceptions and pass them on via the ForceRollback() method.  Throwing an exception from Prepare() (or allowing one to bubble up thru Prepare()) will short-circuit the System.Transactions infrastructure from calling Rollback() on enlisted resources - not something you want to happen.

Nuance 2: Rollback() is not called on your resource if Prepare() votes to rollback

If you call ForceRollback() within your implementation of the Prepare() method, the Rollback() method will not be called on your resource.  Any clean up that typically occurs in Rollback() will need to occur within Prepare() IF your Prepare() method votes to rollback.  For example, if your Prepare() method acquired any locks (e.g. "row locks", "table locks", etcetera) you will likely want to release them in the Prepare() method right before you vote to rollback.

Moving Forward

I hope that this is useful to you - I haven't seen this behavior documented anywhere, but that could be my own fault.

I have no doubt that I will find additional implementation nuances when it comes to System.Transactions.  When I do, I'll be sure to document them here.


I'm Going To The PDC!!!

Monday, 16 June 2008 09:27 by jordan.terrell

I can't wait to see what Microsoft has cooking now!  The 2005 PDC was great because of all the LINQ-related language enhancements and WinFX content.  I'll keep you posted.



Categories:   .NET | Programming
Actions:   E-mail | | Permalink | Comments (0) | Comment RSSRSS comment feed

I'm Not Dead Yet

Tuesday, 3 June 2008 10:34 by jordan.terrell

It's been a while since I've posted, so I thought I'd give a brief update.  I got really sick for two weeks (bad cold, sinus and ear infection - the works), and then I had a week long vacation, so naturally all kinds of things started to pile up that I needed to work on - posting on my blog got pushed to the bottom of that list.

Hopefully in the next month I will get back to posting regularly - as for my iSynaptic.Commons framework, I'm still making some non-code changes (build scripts, licensing, packaging, ect) to get it ready for release and I'm behind on that too.  One of these days I'll actually get around to releasing it.

Thanks for your patience...

Categories:   General
Actions:   E-mail | | Permalink | Comments (1) | Comment RSSRSS comment feed