3

If I have a custom type (or maybe an enum) like for ex. a Range:

Public Class Range

    Sub New(minimum As Single, maximum As Single)
        Me.Minimum = minimum
        Me.Maximum = maximum
    End Sub

    Public Property Minimum As Single 
    Public Property Maximum As Single 
    Public ReadOnly Property Delta As Single 
        Get
            Return Maximum - Minimum
        End Get
    End Property
End Class
'-----------
'Some methods...

This type should be used in the domain model(implementing DDD), in the business logic when doing stuff and also in the data layer, where it will be stored as a complex type.

So :

  • should I define such classes in a Project App.Common and reference this assembly everywhere (my choice for now, but don't know if having references in domain model project is an anti-pattern?)
  • should I define it in my domain model and reference my domain model everywhere where it is needed. (maybe better? since Domain model is core in DDD, but the type is not a domain or value object...)
  • should I create different classes for each layer (which don't make sense to me, since I want to handle it like another type and not as Object)?

EDIT In my case I use range as a MeasuringRange for measure devices. For ex. a thermometer that can measure from 0°F-250°F:

public class Thermometer
{
    public Thermometer(Range measureRange)
    {
        this.MeasureRange=measureRange;
    }

    public Range MeasureRange {get;set;}
}

At the moment it's also used in the DataLayer (using EF Code First) to store the device range as a complexType (EF creates fields MeasureRange_Max and MeasureRange_Min.

It's also used in services in the BLL when doing some measurements with the devices.

  • How does range relate to your domain? The thing that strikes me about it is that it isn't enumerable. – Aluan Haddad Jan 2 '18 at 13:48
  • 1
    In my case I used it as a measuring range for some measure devices. For ex. a thermometer can measure from x°C to y°C. – R. Gomez Jan 2 '18 at 14:17
  • that sounds like a domain object for sure. – Aluan Haddad Jan 2 '18 at 14:34
3

I don't believe that there is an authoritative answer to this.

My guess is that we should treat Range as a sort of domain agnostic convenience for implementation. It's somewhat analogous to System.Collections in that regard.

Also, it seems like that the application component might want to use it even if the domain component does not (and vice versa), which implies that it belongs in a separate component that they might both share.

should I define such classes in a Project App.Common and reference this assembly everywhere

This is the approach that makes the most sense to me.

should I define it in my domain model and reference my domain model everywhere where it is needed.

Probably not - the domain model is a lot of weight to pull in for a library. Unless Range and Delta are part of your domain language, the dependency is really an implementation detail that should not be obvious to the clients of the domain model.

should I create different classes for each layer (which don't make sense to me, since I want to handle it like another type and not as Object)?

I don't see much advantage there, in the same way I don't see an advantage to duplicating a collection across multiple components.

  • Thanks for the reply. That's the way I was thinking about it. I think I will keep those classes and enums in a common project, that also stores Log and such services. So they can be easily accesed. I don't see a range like sth that is coupled to my domain...I see it more like a "custom type", like it can be a string. I also thought just using Min and Max but a class gives me more flexibility. – R. Gomez Jan 2 '18 at 14:37
2

One big idea in DDD is that the Domain layer does not depend on any other layer (i.e. Presentation, Infrastructure, Application etc). This rule exists so this layer contains pure, easily testable, side effects free, business logic.

But, in order to implement this business logic, we need to use and re-use some basic classes like lists, email addresses, ranges (like yours), time intervals etc. These classes, although there are not from the Ubiquitous language, they are important supporting constructs. They keep our code DRY.

According to the DIP, the Domain layer should own these constructs. This implies that they should reside in the Domain layer. You can put them inside a nested directory, something like Domain/Base, in order to separate them from the Entities, Aggregates and Value objects but to keep them close.

  • I also think about this, but then I'll need a reference to my domain model EVERY time I want to declare some field, prop or something as range. So at the end I'll be referencing directly my DL in all my layers (apart from UI). And that's it's something that makes me feel strange... – R. Gomez Jan 2 '18 at 14:31
  • It is ok to reference Domain Objects (aggregates, value objects) from any other layer. – Constantin Galbenu Jan 2 '18 at 14:36
  • and what about referencing libraries in my DL project? For example in my specific case some of my domain models (I think they are more value objects...I'm still learning DDD :P) are measure devices, and for them I wrote a control Library that contains the BL to control the devices. So DDD's "behaviour" of this classes resides in a 3rd-party lib (under my control), so I need them to build my domain....or I'm overseeing/missunderstanding sth? – R. Gomez Jan 2 '18 at 14:40
  • @R.Gomez That control library that controls a physical device should stay in the infrastructure. You need to be careful to split the business behavior (the DDD kind of behavior) from the low-level IO functions. The applications that control physical devices are a special case where DDD does not apply 100% because they contain a lot of infrastructure logic. – Constantin Galbenu Jan 2 '18 at 14:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.