1

I have a Business Layer, where I have put all the Entities of the Domain Model. Also there are Domain Services, where I put Domain Logic related to n Entities. One entity is :

public class TypeOfIceCream
{
    public int Id {get; set;}
    public string Name {get; set;}
}

public class IceCreamOrder
{
    public int Id {get; set;}
    public int IdTypeOfIceCream {get; set;}
    public double Price {get; set;}
}

My problem arises when I have to assign the typeOfIceCream to an IceCreamOrder. I have a Domain Service:

public class IceCreamOrderDeliveryDomainService
{
     readonly IRepository<TypeOfIceCream> _repoTypeOfIceCream;
     //...

     public IceCreamOrder SetXXLIceCream(IceCreamOrder order)
     {
         //...other domain logic
         var typeXXL=_repoTypeOfIceCream.GetById(1); //How to avoid this!! I need to assign the Id of the state
         order.IdTypeOfIceCream= typeXXL.Id;
     }
}

As you see, my domain model, got infected by hard-coded Ids, but how can I avoid that? I want to assign specific types to IceCreams. I know the Ids, cause they are master-data that I am inserting while creating the Model and won't never change.

In the answers/comments someone is telling me to do this. What do you think?

public class IceCreamOrderDeliveryDomainService
{
     readonly IRepository<TypeOfIceCream> _repoTypeOfIceCream;
     readonly IMasterData _masterData;

     public IceCreamOrderDeliveryDomainService(
         IRepository<TypeOfIceCream> repo,
         IMasterData masterData) {
         //....
      } 
     public IceCreamOrder SetXXLIceCream(IceCreamOrder order)
     {
         //...other domain logic
         var typeXXL=_repoTypeOfIceCream.GetById(_masterData.XXLIdTypeOfIceCream); //How to avoid this!! I need to assign the Id of the state
         order.IdTypeOfIceCream= typeXXL.Id;
     }
}
  • Why did you hard-code it? Why don't you get that ID from somewhere else? Like the requestor of the ice cream, maybe? – Robert Harvey Aug 26 '19 at 15:45
  • If you have a fairly fixed amount of types of ice cream, you could make TypeOfIceCream an Enumeration instead of a class. – Rik D Aug 26 '19 at 15:47
  • SetXXLIceCream() violates open/closed principle. You should get type of ice cream from a derived class method, or it should be injected. – QuietSeditionist Aug 26 '19 at 17:37
  • @RobertHarvey I hardcoded them because I know they exists in the database, because they are in the seed data of my model. – X.Otano Aug 26 '19 at 18:46
  • @QuietSeditionist You mean , that I can inject the Ids as a MasterData interface (or something similar)? – X.Otano Aug 26 '19 at 18:53
0

As you see, my domain model, got infected by hard-coded Ids, but how can I avoid that? I want to assign specific types to IceCreams. I know the Ids, cause they are master-data that I am inserting while creating the Model and won't never change.

What I think you'll see in most cases is an extra level of indirection

var VANILLA = 1;
var typeXXL=_repoTypeOfIceCream.GetById(VANILLA); 

Which is to say, we replace the domain agnostic primitive and replace it with a name that correctly expresses the domain semantics.

Then we try to move the assignment into a part of the code that makes sense.

var typeXXL=_repoTypeOfIceCream.GetById(MasterData.VANILLA);

You've probably seen this sort of approach in the handling of HTTP status codes.

int SC_SUCCESS = 200;

An example to consider is UN/LOCODE, as used by Citerus in the DDD Cargo Sample. The standard abbreviations are part of the language of the domain -- if shipping is your domain, you know about these codes, and perhaps even the revision protocols for them.

It would be perfectly reasonable to have a single module in your solution that knows how to represent locations as codes (strings), with your domain logic knowing the name for a code that it wants without necessarily knowing the string representation.

For literals - especially literals that are stable for the lifetime of the solution, it's largely a matter of taste whether your domain logic references the data directly MasterData.VANILLA or indirectly MasterData.vanilla(); whether to reference that name directly at the location that you need it, or instead pass it in as an argument (for instance, via a domain service).

| improve this answer | |
  • Please, check the last part of the question again. What do you think? Is that looking nice for you? – X.Otano Aug 26 '19 at 19:00

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