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:
- Seperation of complex business logic and data access concerns.
- Generic business object design that supports re-usability.
- Lends itself to dependency injection.
- 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?
- It allows you to re-use business logic between implementations with different data requirements.
- 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.
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."
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;
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;
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) => {}));
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.
Scratched my head with this one a bit, but here is the solution:
- Obtain the IntPtr equivalent of the char*:
const unsigned char* data;
System::IntPtr dataptr((int)data);
- 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);
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.