views:

269

answers:

2

I've got a set of business/domain classes (for a calendar) that are going to be exposed in an internally-public API. In the same API, there are data objects that directly mirror the underlying database structure (NHibernate mapping, but that's unimportant).

What I need to do is build typed collections of those objects, so the days on the calendar can each contain a set of appointments, reminders, etc., which come from the database.

One solution is to "tag" each data object using a marker interface from the domain model:

public class CalendarAppointment : PersistentEntity, ICalendarObject

But then I've put business/domain model stuff in with my data model.

Another solution is to wrap the data model classes as follows, and expose/use those in the calendar API:

public class Appointment : CalendarAppointment, ICalendarObject

But this introduces very obvious coupling.

A third solution is to use a DTO, but I would need to expose every field in the data object in the DTO... so it doesn't seem to make sense to create a DTO in the first place.

Which is the best option here, or is there a better option?

This is a .NET 2.0 project, if that makes a difference.

A: 

Its always tempting to bypass DTOs when your business-domain model and your data model are looking awfully similar.

Have you considered reworking your public API so it doesn't actually look that 'verbose'?

If you can't really do this, bite the bullet and go DTO, as the price of sending NHibernate objects to client code using your API is usually paid in tears of blood.

Florian Doyon
I should clarify, and I will edit my question. The API of which I speak will be internally public -- the plan is that it will be used to develop our base product, and also to extend the functionality of the base product (this is part of a legacy system migration where several clients have huge deviations from the base product). We've separated the data _structure_ classes (as above) from the data layer querying, but both of those things have to be exposed in the API.
Jon Seigel
A: 

We decided that the calendar objects are implicitly tied to the database, so that kind of coupling would be okay. We ended up going with solution #4 (encapsulation FTW):

public class Appointment : ICalendarObject
{
    public CalendarAppointment Item { get; }
}
Jon Seigel