Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

App-level settings in DDD?

Just wanted to get the groups thoughts on how to handle configuration details of entities.

What I'm thinking of specifically is high level settings which might be admin-changed. the sort of thing that you might store in the app or web.config ultimately, but from teh DDD perspective should be set somewhere in the objects explicitly.

For sake of argument, let's take as an example a web-based CMS or blog app.

A given blog Entry entity has any number of instance settings like Author, Content, etc.

But you also might want to set (for example) default Description or Keywords that all entries in the site should start with if they're not changed by the author. Sure, you could just make those constants in the class, but then the site owner couldn't change the defaults.

So my thoughts are as follows:

1) use class-level (static) properties to represent those settings, and then set them when the app starts up, either setting them from the DB or from the web.config.

or

2) use a separate entity for holding the settings, possibly a dictionary, either use it directly or have it be a member of the Entry class

What strikes you all as the most easy / flexible? My concerns abou the first one is that it doesn't strike me as very pluggable (if I end up wanting to add more features) as changing an entity's class methods would make me change the app itself as well (which feels like an OCP violation). The second one feels like it's more heavy, though, especially if I then have to cast or parse values out of a dictionary.

like image 482
Paul Avatar asked Nov 23 '09 21:11

Paul


People also ask

Is DDD same as microservices?

DDD provides an avenue to facilitate the development of highly cohesive systems through bounded contexts. Microservices is an implementation approach that encourages you to focus your service boundaries on the business domain boundaries.

What is infrastructure layer in DDD?

The infrastructure layer is how the data that is initially held in domain entities (in memory) is persisted in databases or another persistent store. An example is using Entity Framework Core code to implement the Repository pattern classes that use a DBContext to persist data in a relational database.

What is DDD pattern in microservices?

Domain-driven design (DDD) for building and decoupling microservices. Domain-driven design (DDD), first coined in a book by Eric Evans, is an approach used to build systems that have a complex business domain.

Is DDD layered architecture?

As represented in the figure 3, the DDD layered architecture contains four levels of abstraction which are the user interface layer, the application layer, the domain layer and the infrastructure layer [2]. Each layer depends only on layers of the same level as well on the ones beneath it [2]. ...


1 Answers

I would say that that whether a value is configurable or not is irrelevant from the Domain Model's perspective - what matters is that is is externally defined.

Let's say that you have a class that must have a Name. If the Name is always required, it must be encapsulated as an invariant irrespective of the source of the value. Here's a C# example:

public class MyClass
{
    private string name;

    public MyClass(string name)
    {
        if(name == null)
        {
            throw new ArgumentNullException("name");
        }

        this.name = name;
    }

    public string Name
    {
        get { return this.name; }
        set
        {
            if(value == null)
            {
                throw new ArgumentNullException("name");
            }
            this.name = value;
        }
    }
}

A class like this effectively protects the invariant: Name must not be null. Domain Models must encapsulate invariants like this without any regard to which consumer will be using them - otherwise, they would not meet the goal of Supple Design.

But you asked about default values. If you have a good default value for Name, then how do you communicate that default value to MyClass.

This is where Factories come in handy. You simply separate the construction of your objects from their implementation. This is often a good idea in any case. Whether you choose an Abstract Factory or Builder implementation is less important, but Abstract Factory is a good default choice.

In the case of MyClass, we could define the IMyClassFactory interface:

public interface IMyClassFactory
{
    MyClass Create();
}

Now you can define an implementation that pulls the name from a config file:

public ConfigurationBasedMyClassFactory : IMyClassFactory
{
    public MyClass Create()
    {
        var name = ConfigurationManager.AppSettings["MyName"];
        return new MyClass(name);
    }
}

Make sure that code that needs instances of MyClass use IMyClassFactory to create it instead of new'ing it up manually.

like image 167
Mark Seemann Avatar answered Sep 18 '22 17:09

Mark Seemann