ArMaN
ArMaN

Reputation: 2407

Which layer should i declare enums?

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.

Upvotes: 27

Views: 18509

Answers (5)

mko
mko

Reputation: 7325

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://learn.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/enumeration-classes-over-enum-types

Upvotes: 3

Binarynam
Binarynam

Reputation: 154

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.

Upvotes: 2

hazjack
hazjack

Reputation: 1715

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.

Upvotes: 23

Johnathon Sullinger
Johnathon Sullinger

Reputation: 7414

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.

Upvotes: 19

Ehsan
Ehsan

Reputation: 32681

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.

Upvotes: 8

Related Questions