views:

245

answers:

5

I'm trying to figure out how to share my entities between the data, business, and UI tiers. Is it best to create a separate project for these entities that will be referenced by all the tiers? What about Enums and custom exceptions? I have some enums used only by the UI project, and some that are used by the Business. Does this mean I should have two separate Enum folders: one in the Business project and one in the UI? Similarly with Exceptions? Till now, I have been maintaining the entities, enums, and exceptions all in one separate project that are referenced by all the 3 tiers.

My Business project has Manager classes (like ProductManager.cs) which have methods like List GetProducts() and SaveProduct(Product), etc.

+1  A: 

I usually put enums and custom exceptions together with the interface definitions in a separate project.

Otávio Décio
+1  A: 

If you need the entities in all tiers then using a separate project is (imo) the best way.

rdkleine
+2  A: 

If these entities have a semantic meaning across all of these tiers, I would recommend putting them in a separate project/assembly that all tiers have knowledge of.

If you have entities that are specific to one layer, I would confine them to that layer. So, for example, you wouldn't allow UI code to throw a Business Layer exception, or the Business Layer to use a UI enum.

Depending on what you are doing, there may be no harm in keeping layer-specific types in the same project/assembly that you keep your shared types, but I would consider confining them to their own layer a best practice.

Phil Sandler
+1  A: 

You've been doing the right thing. Creating a separate project with all entities are almost always the way to go. If the enums and exceptions are entity-related, they belong in there as well.

Oliver John
Could enums and exceptions be considered as entities as well?
Prabhu
+2  A: 

Think encapsulation. Place them at the scope where they are needed, and not in a wider scope.

If something is only used within the UI layer, don't expose it to other layers. But if it's used across two or three layers, then define it in the lowest-level layer (e.g. if UI sits on Business Logic which sits on Database, then something used in BL and UI can just be defined in BL). Or if something is more or less global, move it to a third party shared library.

Also, try to minimise the need for shared entities in the first place: e.g. It is recommended (for good reasons) to avoid custom exceptions. Most of them can usually be represented by an existing system exception with a bit of extra information (e.g. an InvalidOperationException with details in the message), minimising the need to handle a whole new class of exceptions everywhere - and of cours eliminating the need to decide where to define the custom exception type.

Jason Williams