Reputation: 1022
I'd like to use the same enum across three tiers of my application (presentation -> bal -> dal). I defined the enum in the data layer and I want to use the same enum in the presentation layer (the presentation layer does not have a reference to the data layer). Using someone else's answer to what I think is a similar question, I've built the following enum in the business layer:
namespace bal
{
public enum TransactionCode
{
Accepted = dal.TransactionCode.Accepted,
AcceptedWithErrors = dal.TransactionCode.AcceptedWithErrors,
InvalidVendorCredentials = dal.TransactionCode.InvalidVendorCredentials,
BrokerOffline = dal.TransactionCode.BrokerOffline
}
}
Is this an appropriate way to construct enums between the tiers?
Upvotes: 5
Views: 3304
Reputation: 1673
My answer is slightly more "elaborate" than the other ones because I have two extra criteria :
The enums don't fit well in there, because if we wanted to make it consistent (references-wise) we would need to create "versioned" enums too. But then if they're shared with the data layer then that versioning starts invading it (imagine a bad "int" value reaching a column in the Db because the DTO class have rearranged their enums in a new version. Not good).
Problem: If we put our enums in a "shared" project that already contains other shared stuff (some constants, some utility extension classes, etc.) then we share that with the clients!
The solution I'm about to choose is to have a project only for Enums
. Not just Shared
stuff in general, but strictly Enums. I think I've seen that in the past in other projects and it seems right.
Upvotes: 0
Reputation: 32960
Your enum is actually part of an API. When you think about layered software, its often hard to think about shared types, but most of the time, a set of types is always shared accross layers. Instead of just thinking about the standard layering:
Presentation -> Business -> Data
Try thinking about it like this:
Presentation -> API
|-> Business ----^
|-> Data ----^
Where API is a shared aspect of your system. The API contains any shared data types, entities, enumerations, service interfaces, etc. The API can be isolated into its own library, and reused in your presentation, while also being the gateway to your domain (which is business and data logic.)
Upvotes: 3
Reputation: 46360
In these cases, I usually seperate out my "data types" into its own small assembly. Then reference that assembly everywhere you need it.
Upvotes: 2
Reputation: 35117
If it were me I would create another project with this kind of stuff in it and have all the projects reference that.
Upvotes: 2
Reputation: 63126
This really depends on how your interactions are going on. The translation of a dal.TransactionCode to bal.TransactionCode will most likely not work in any operation where you are trying to set equality.
If you are truly passing it all the way around and NEED to across all layers, I would either define it at the bal layer, or reference the dal from the UI.
Upvotes: 0
Reputation: 1500873
One approach is to have one "layer" (well, not really a layer as such) which is shared across all layers.
I blogged about this a while ago (in a blog/project which is now dormant, unfortunately). It may seem "impure" but it makes life a lot easier in many ways and reduces duplication. Of course, it does then reduce flexibility too - if you ever want the presentation enum to be different from the data layer enum, you'd have to refactor...
Upvotes: 7