How can I completely separate my Business and Data Layers?

c#, design-patterns

Solution

This is a more general problem than just how to separate Domain Model from Data Access. The same problem occurs when you attempt to separate your Application Logic from your Domain model, your Presentation Model from Application Logic and so forth.

The common solution is a technique called Dependency Injection (DI). Some people also refer to it as Inversion of Control (IoC).

The seminal text on the subject was Martin Fowler's article Inversion of Control Containers and the Dependency Injection pattern, but we have come a long way since then, so be sure to examine some more recent texts as well.

You can implement DI manually, like described in this blog post, or you can let a DI Container (i.e. a framework) do the work for you.

Common DI Container are:

- Windsor

- StructureMap

- Spring.NET

- Unity

Problem

I currently represent my Business Layer and Data Layer in a single project in my application. I have very good separation of concerns between the two sets of classes. However, My Data Layer classes take as parameters and return my business objects. So I will have code that loosely resembles (please don't be too critical of this code, my production code doesn't look much like this): ``` //business class fragment public bool Save() { if(this.IsValid) { //DataProvider is one of many data access classes that implement an IDataProvider interface. Switched elsewhere in the class. This allows switching of Database providers, xml, etc. DataProvider.Save(this); return true; } return false; } public List<MyBusinessObject> GetObjectsByCriteria(string criteria) { return DataProvider.GetMyBusinessObjectsByCriteria(criteria); } ``` I don't want my business classes to have to deal with DataSets any more than I like having my Data Layer classes deal with Business Classes. I have read up a lot on Data Access Objects, or Data Transfer Objects to possibly solve this problem, but the this seems like an anti-pattern case for those patterns. What can I do? How to I elegantly achieve complete separation of these two layers of my application?

Original source