13

I have a C# N-Layer Project that has 5 Layers: 1-Infrastructure 2-Domain 3-AppService 4-Distributed Service 5-Presentation

I want to use enums in my project. but I don't know which layer describe them. I have two ideas about it.

1- declare enums in Domain and pass through network by WCF DataContract.

2- declare enums in a class library project(ex: in common layer) and build it as dll and use it in all layer.

Help me to choose one.

ArMaN
  • 2,087
  • 2
  • 28
  • 47
  • 1
    Depends which layers are going to access the enums..if all layers are going to need access, you should probably create a Core layer and put them in there – d.moncada Jun 30 '14 at 03:44

5 Answers5

16

I would share my opinions regarding this concern:

  • Strategy 1: Domain layer defines an enum AddressType (having Home, Work...). Service layer defines another enum AddressTypeDto with all values Home, Work...) and they actually map from AddressType ==> AddressTypeDto. On presentation layer, the type AddressTypeDto will be used also.

  • Strategy 2: Create a layer (not really a layer) which contains common enum types and use it in different layers from Domain/Service/Presentation

The S1: it keeps all layers Domain/Service/Presentation independent but requires more classes to present the same thing.

The S2: it keeps all layers Domain/Service/Presentation independent but requires them depending on "common" dll.

I saw applications that implement one of the two strategies. I will choose the Strategy 2 as it's more efficient. Almost applications often have common things, some enum types should be there.

hazjack
  • 1,467
  • 10
  • 25
  • 1
    Nice answer. I am going with you. But as you said, strategy 2 is more efficient and DRY. In a DDD perspective, you can use it in the domain and app. – Lincoln Pires Nov 11 '15 at 13:37
10

It depends on where you need to use the values that the enum's represent. If these are values that your presentation layer would need, then that is where they should go. If it is something that your service layer would rely on, then you need to put them in there.

I'm not to sure the best approach is to lump all of your enums into a single location. They should be spread-out across the app, at the lowest layer that relies on them, usually in the same namespace as the class that consumes the enum and performs some logic on them.

If the app and the domain will use them, then declare them in the domain and pass the value through the network.

Johnathon Sullinger
  • 6,380
  • 4
  • 33
  • 82
6

If that needs to be used only in some specific layer, then declare it in that layer. If you want to use it in all the layers then it should be declared in some common layer and a reference should be added to all the layers that are using it.

Ehsan
  • 28,801
  • 6
  • 51
  • 61
1

In multi layer solutions, each layer should only depend on the layer below it. For example if you are working using DDD you would probably have this

Presentation layer (should depend on app layer) Application layer (should depend on infra layer) Infrastrucure layer (should depend on domain layer) Domain layer (should not depend on any layers)

So basically Enums are usually part of Domain, and if you dont want to map, map, map, then you should add additional dependencies to your presentation and application layers (depend on domain). If you want to keep your architecture clean as a wistle, then all you can do is - map. Personally I dont enjoy mapping enums, since if there is nothing to map you would have to invent new enum type or throw an Exception. Both solutions are not as clear as I would like them to be.

UPDATE

Also consider using enumeration classes

https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/enumeration-classes-over-enum-types

mko
  • 4,825
  • 8
  • 45
  • 97
1

I've Personnally been working on a oniony-DDDish solution, and having duplicate enums and mappers in ALL the layers is damn tedious and can never feel like it's clean. My solution was to have all enums in the domain layer, then as soon as the data goes to outer layers (well except the app service layer of course), it all becomes int casts. Think about it : why would you still need the enum ? You're supposed to have all the logic in the domain layer, you're not supposed to do stuff like 'if (bar.type == types.foo)' outside the domain layer, it's just anti pattern. If you really need the enum value again in another layer, just declare a duplicate enum an cast it back ... It might typically happen in a test assembly.

Binarynam
  • 144
  • 7
  • Best answer to me. I was overthinking my solution and I ended up passing string value from API from presentation layer down to the layer where I really needed that enum and parse it. – Tomasz Sikora Apr 15 '21 at 09:00