views:

191

answers:

2

Consider a layered application where the DataLayer has a certain class with all the data access stuff in it, and above that the business layer has a class which can take in the constructor a data object, and has other overloads as well. Ex:

namespace Datalayer
{
    public class dataObject
    {
        // all the class here
    }
}  

namespace BusinessLayer
{
    public class busObject
    {
        busObject(){}
        busObject(Datalayer.dataObject parm) {/*do something with parm*/}
        busObject(int objectID) {/*go get the dataObject with the ID*/}
    }
}

Layers above (a UI layer probably) should not need to have a reference to the datalayer in this model. However, with the ctors set up in the business layer in this way it is required. Can someone explain why?

I would prefer to have my ctors this way, but do not want that datalayer reference in the UI layer. To get around it to date I have removed that last ctor and added a method as such to set up the object after instantiation:

Select(int objectID) {/*go get the dataObject with the ID*/}

Is it possible in any way to leave my constructors as above without requiring that reference?

sheldon

A: 

Define interface for DataLayer and either use DI container or use provider pattern to get the concrete instance of the DataLayer.

epitka
+1  A: 

Currently at my company, and this might be way wrong... but it works for us, our business objects inherit from interfaces to our data objects. We don't normally compose our business objects from our data objects; which is what it looks to me like you are doing.

Edit: Added the interfaces that I left out previously. My apologies. That's what happens when you are rushing.

// in it's own dll: Datalayer.Interfaces.dll
namespace Datalayer.Interfaces{
public interface IdataObject
{ // interface declaration }

namespace Datalayer {
public class dataObject: IdataObject
{// all the class here } }  

namespace BusinessLayer {
public class busObject : IdataObject {
  busObject(){} 
  busObject(IdataObject dataObject) {} 
  busObject(int objectID) {//go get the dataObject with the ID}
}}

One must still include the reference to the interfaces, but no longer the reference to the actual data layer. When we need to map the business object to the data object, we then roll our own mapping or use AutoMapper.

John Kraft
actually, I'm seeing the same issue if I inherit the data layer from the business layer: The type 'DataLayer.dataObject' is defined in an assembly that is not referenced. You must add a reference to assembly 'DataLayer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.Are you sure your top loayer doesn't have a reference to the datalayer?
sheldon
@sheldon - I'm following you now. I misunderstood part of what you were asking. I just went and looked at our code, and we are using interfaces to the datalayer objects; similar to what epitka suggested. We then put those interfaces in their own dll (e.g. namespace DataLayer.Interfaces.dll). I'll edit my answer appropriately.
John Kraft