Search code examples
c#wcfmongodbdata-access-layern-tier-architecture

What is the inheritance pattern between data models and services model?


One of our products contains multiple WCF services whose business layers all sit on top of the same data access layer which provides access to a NoSql database (mongodb):

  WCF   WCF   WCF
   |     |     |
   BL    BL    BL
   |     |     |
 Data Access Layer        <-- PageInfoResult currently defined here
         |
      mongodb

Because each of the services contains one or more methods which either accept or return a particular type (PageInfoResult) which is also stored directly in the database, the class PageInfoResult is defined in the DAL with both Bson serialization attributes (for mongodb) and data contract serialization attributes (for WCF).

Example:

[DataContract]
public class PageInfoResult
{
    [BsonId]
    [DataMember]
    public string PageUrl { get; set; }

    [BsonElement("status")]
    [DataMember]
    public int HttpStatusCode { get; set; }

    [BsonElement("score")]
    [DataMember]
    public int OurProprietaryPageScore { get; set; }

    [BsonElement("data")]
    [DataMember]
    public SomeOtherClass OtherData { get; set; }

    // ... other properties ...
}

So the specific question are:

  1. should each of the WCF services redefine and then graph to the DAL's data models or can the DAL legitimately be the only place where the models are defined?
  2. If each of the services should redefine each of the models in the DAL, should the service models inherit from the data models (or vise versa)?

In a more general sense:

  1. what is the proper, object oriented approach to defining very similar (or identical) service and data models?
  2. Is there a difference in approach when dealing with a schema vs. schema-less database (MsSql vs. MongoDB)?

Solution

    1. Data models and WCF contracts are two completely different things. They should not be the same! If they're the same, your service layer is too tightly-coupled to your data access layer.

    2. My opinion is "no". Inheritance would still imply tight-coupling between the two.

    Best to think of the service layer in terms of what exactly you're exposing to your clients. Your WCF data contracts should house only the necessary info for your clients to call your service.

    The "translation" between the service layer's data contracts and the data models as you call them should propbably happen in your business layer. Better yet, think of your business layer as the "consumer" or "user" of the data contracts and the data models.

    Again, that's just my opinion, but i do think it's best to think of them as being completely separate.

    EDIT: (from comment) Sometimes we strive to decouple and add layers of complexity that only complicate the architecture of the solution. In contrast to my answer, perhaps "keep it simple" then? If that's the case, no need to involve inheritance, just do what you're doing if it works for you.