Blog Stats
  • Posts - 8
  • Articles - 0
  • Comments - 0
  • Trackbacks - 0

 

Tuesday, April 17, 2012

A simple pattern to separate Business Logic from Data Access.



Whether we like it or not, unlike conventional engineering structures like bridges and buildings, software will always be engineered and built to be changed at some future point. It is the nature of the business requirements that we are there to serve. Everything changes. Constantly.

Software Engineering is the science we busy ourselves with in order to cope with these changes, and a lot of patterns and practises have evolved as the artifacts of our constant quest to accommodate changes in our programs.

I've recently been assigned the task of extending some legacy C# back-end server code. The code used typed datasets and stored procedures for data access. Over time, with lots of hasty maintenance being performed, the line between business logic and data access have blurred to the extent that the code has become both extremely hard to understand and prone to regression bugs. Everyone knows that such code doesn't lend itself to being extended nor re-used.

I would like to present an application design pattern here which proved to produce an elegant implementation with the following benefits:
  1. Seperation of complex business logic and data access concerns.
  2. Generic business object design that supports re-usability.
  3. Lends itself to dependency injection.
  4. Unit-testability through the use of RhinoMocks.
From the bottom-up: The data access layer.

There are many arguments these days against stored procedures. It is a common conclusion amongst most application designers that the benefits of using an ORM are far superior to those of stored procedures. There are, however, certain production environments where stored procedures still have a place, and the reasons for this are many, sound for the most part, and not the primary focus of this article. I will rather be addressing the question of how to structure your application so that your business object layer is data access-agnostic. Whether you are stuck with using datasets, or are in a position to use an object-relational mapping(ORM) technology like NHibernate or Entity Framework, I believe the pattern I present here will prove equally beneficial to your project.

Also, the poison here is the easily learned traditional view of the domain object, which in many peoples minds "knows how to persist itself". This little phrase captures the essence which i'm trying to combat in this article. I believe it is this view which often destroys the seperation I'm advocating here, without which, you are left with, more often than not, an unmaintainable mess.

How to prevent writing data access logic into your Business/Domain object layer

Rule #1: Wrap your Data Access objects

I've seen some sources on the subject on the web playing down the importance of these very simple wrapper classes citing that it is a lot of work for not much benefit, however, this is the very LEAST of what you must do in order to bring about this most important of seperation between concerns. Whether you are using datasets or mapped NHibernate entity objects, you MUST resist the temptation to reference these entity/dataset objects directly in business logic code. The way to achieve this is to write a wrapper class around these often volatile database objects, and reference the wrapped object instead. I say it is the least of what you must do because I now arrive at the point for motivating my rule #2:

Rule #2: Program all your business logic against an interface of the domain object, not the domain object itself

Why an interface?
  1. It allows you to re-use business logic between implementations with different data requirements.
  2. Those familiar with RhinoMocks should be smiling right now...(for the rest: in general RhinoMocks only allows you to mock interfaces)
Re-use of business logic? Suppose you have an object that needs to be manipulated by a processing pipeline, for instance: an accounting application has to make an Order book entry. If my domain process class is OrderWriter, and I make it operate on an IOrder instead of a concrete Order implementation, do you see the opportunity to potentially use OrderWriter to be able to populate two different kinds of orders, both implementing IOrder? As you can start to visualize, my data access object wrapper object implements IOrder(amongst any others I may choose), an instance of which gets passed to OrderWriter at run-time. When OrderWriter calls IOrder.Save(), the business logic is completely agnostic to how this happens - I have my all-important seperation.

Caveat 1: How do I construct something which is an interface?
Suppose my OrderWriter only uses IOrder's and needs to create a new one? Use the well-known Factory Class pattern. In OrderWriter, in order to construct a new order, I call IOrderFactory.CreateInstance(). In my client code of OrderWriter, I create a concrete implementation MyOrderFactory that implements IOrderFactory, that knows how to construct a new concrete ClientOrder, which implements IOrder. So OrderWriter now looks like this:

class OrderWriter
{
     public OrderWriter(IOrderFactory orderFactory)
     {
          mOrderFactory = orderFactory;
     }

      void WriteOrder(IOrder order)
     {
           order.Save();
           IOrder oppositeLeg = mOrderFactory.CreateInstance();
           oppositeLeg.Save();
     }

     IOrderFactory mOrderFactory;
}


As you can see, our domain class now becomes a dependency injected, unit testable class, where the data access part is easily mocked out by testing the method with a mocked-out IOrder.

var order = MockRepository.GenerateMock<IOrder>();
var orderFactory = MockRepository.GenerateStub<IOrderFactory>();
orderFactory.Stub(x => x.CreateInstance().Return(MockRepository.GenerateMock<IOrder>());

.
.
mOrderWriter.WriteOrder(order);
order.AssertWasCalled(x => x.Save());


and so on.

In my own application, the data access object wrapper class(the one actually implementing IOrder) ended up delegating storage to datarow fields from each of the implemented IOrder property setters, and returning the datarow value in return in the property getter. This way the database access code is nicely isolated from and invisible to the concerns of the business layer.

Tuesday, March 13, 2012

RhinoMocks - How to intercept a and re-direct a method call to a stub using the original parameters



Suppose I have a stubbed interface acting as a proxy for the real object:

IDatabase databaseStub = MockRepository.GenerateStub<IDatabase>();

Now suppose I have a parameterized method which needs redirecting to some utility method, for instance to return some test data:

DataSet IDatabase.RetrieveData(int entityId);

And I have a local utility method in my test:

DataSet GetTestData(int entityId);

and I wish for this method to be called whenever the RetrieveData method is called on the stub.

I make use of WhenCalled and GetArgumentsForCallsMadeOn as follows:

databaseStub.Stub(x => x.RetrieveData(Arg<int>.Is.Anything))
   .WhenCalled((methodInvocation) => {
       var args = databaseStub.GetArgumentsForCallsMadeOn(x =>                             x.RetrieveData(Arg<int>.Is.Anything));
             int lastCallIndex = args.Count - 1;
       methodInvocation.ReturnValue = GetTestData((int)args[lastCallIndex][0]);
}).Return(new Dealer());


The lastCallIndex variable is to capture the most recent addition to the args array, it keeps all arguments throughout the test in this array, so if you are only interested in the most recent call, your arguments array will be the last element in this array.
The return of the blank object at the end is to direct the stub as to the correct return type of the method, otherwise you will receive a run-time exeption : "Method "RetrieveData" requires a return value or an exception to throw."

Thursday, March 1, 2012

C++ CLI - How to test if a derived class derives from a base class



In this case there is a base class:

struct base {};

and a derived class:

struct derived1:base {};

To test if derived derives from base:

return dynamic_cast<base*>(derived*) != nullptr;



Wednesday, February 15, 2012

C++ CLI - How to assign a gcroot instance to a stack based instance


So suppose I have:

gcroot<SomeObject^> someObjectGCRoot;
SomeObject someObjectOnTheStack;

And I want to assign the gcroot object to the stack object.
The solution is to declare the stack object as tracking reference instead of the raw type. So instead of:

SomeObject someObjectOnTheStack;

instead declare:

SomeObject% someObjectOnTheStack;

Then the conversion is easy:

SomeObject^ someObjectHandle = static_cast<SomeObject^>(someObjectGCRoot);
SomeObjectOnTheStack = *someObjectHandle;

Thursday, September 1, 2011

How to create a method stub in Rhino Mocks that performs nothing.


The usual rules for stubbing objects apply:

  • The method has to be public.
  • Generate the stub from the interface and not the physical object to avoid the actual implementation being called.
  • If you want to create a partial stub of an object instead of the interface, the methods you wish to stub HAS to be virtual, or they'll be called as you are stubbing them (this should really be a separate post).
stubObject = MockRepository.GenerateStub<IInterfaceToBeStubbed>();
stubObject.Stub(x => 
x.MethodToBeStubbed(Arg<Byte[]>.Is.Anything, Arg<int>.Is.Anything))
.WhenCalled(new Action<MethodInvocation>( (mi) => {}));

 

Friday, August 19, 2011

ZeroMQ blocking on the constructor for Context on Windows Server 2008


We had an issue once we deployed our .Net 4.0 C# ZeroMQ solution to a Windows Server 2008 instance where the application would freeze up or block, seemingly on the initialization of our ZeroMQ library.

Upon furthter investigation it was discovered that the application was blocking on the construction of each new zmq Context object.

Having exhausted all other alternatives, an internet search revealed a stack overflow post :

http://stackoverflow.com/questions/4718262/zeromq-dllnotfoundexception-using-net-bindings

After installing both the x86 and x64 visual c++ 2010 redistributable packages, the problem went away and ZeroMQ functioned normally.

 

Thursday, August 18, 2011

How to copy from char* to managed Byte array.


Scratched my head with this one a bit, but here is the solution:

  1. Obtain the IntPtr equivalent of the char*:
    const unsigned char* data;
    System::IntPtr dataptr((int)data);
    
  2. Then use the System::Runtime::InteropServices::Marshal class to copy the data into the cli::array<Byte>:
    array<Byte>^ byteArray = gcnew array<Byte>(dataLength);
    Marshal::Copy(dataptr, byteArray, 0, dataLength);
    

 

Tuesday, July 19, 2011

Visual C++ Linker Error (LNK2020: unresolved token) with managed class implementations in .cpp file


It turns out that in order for executable assemblies to successfully link, the simple reference to the managed assembly is not enough on its own. Although this is sufficient for the compiler, the linker also needs to be told where to find implementations. This is done through setting the "Use Library Dependency Inputs" to Yes under Project Properties->Configuration Properties->Linker->General.

 

 

Copyright © cdpcodingblog