5

This question is asked on SO and this site often it looks like. "How do I do a dynamic enum?" Answers range from you shouldn't to possible compile time solutions. Now my question is do I want a dynamic enum that is generated from look up tables in the DB, or do I want something else that is similar?

I have a solution using T4 at build time to generate enums from DB tables, that works fine. But now some of the look up tables have an 'active' flag on them. Does this mean they are not look up tables anymore? If that is changed I want to somehow regenerate my code without having to redeploy. These tables will not change often.

Currently the app when it wants to populate a dropdown or something will query the DB. But if the values mostly remain static, why go to the DB every time, hence the use of enums. It also has the added benefit of getting rid of magic strings and numbers.

Would static structs be better? Some sort of caching for the look up tables? Any advise welcome.

2 Answers 2

5

Don't go to the DB every time. Go to the DB at process start; load into readonly dictionaries your lookup data, and call it good. Stuff changes underneath, you need to restart the app to re-grab those dictionaries.

Alternatively, look at actual resource cost of looking the data up every time, if your app isn't significant enough for this to matter, just let it lookup the data everytime via join.

Cache expiration is a complex thing but two very simple techniques come to mind:

  • Lock your lookup tables down to being updated by the app and those updates can signal a reinstantiation of your read-only lookup table dictionaries, this is so long as you don't need to worry about people changing the lookup tables directly through management studio or otherwise.
  • Using SQL server's message broker triggered on updates to lookup tables to send a message to your running app which signals it to replace it's readonly dictionaries with updated versions. This is presuming the updates will be manual SQL scripts

Alternatively use a proper cache like appfabric or memcached for these where you can have appropriate cache expiration if you need. This seems like overkill for what could really be served just fine by my initial suggestion, most systems have admins turn off their app when they go to update their DB directly anyway, and turn it back on only after DB updates are finished.

In summation:

No, you do not want dynamic enums, this goes against what an enum is even for

Enums are named consts. Remember that, consts. As soon as you want a group of key-value pairs you are starting down the path of hashtable/dictionary/associative-array or whatever word you wish to call them, that is precisely the purpose of such structures. Not the purpose of enums.

3
  • I was thinking of using a SQL watcher to update the dictionaries, I believe that uses the SQL Broker. I know what an enum is for. In this case they are still constants, with a active flag. I didn't want to have to recompile and redeploy to update added entries. Or restart the app if possible. 99% of the time this wouldn't be needed.
    – nportelli
    Jan 29, 2013 at 13:53
  • Sounds like a great idea, but again enums are for fixed consts that won't be added to or removed from or changed in any way, lookup tables always grow and change. Dictionaries are meant to grow and change. Jan 29, 2013 at 14:17
  • @nportelli anytime you have any important cache like this, another good approach is to always (if you have authorization-controlled interfaces already a part of the system like most websites have an admin area) create a simple refresh-the-caches interface. Lazy loaded dictionaries instead of read-only is another approach that is acceptable. Again the important thing is to start thinking dictionaries, not enums and suddenly all these approaches come to mind, which is the sign that dictionaries are what you actually want. You know you want an enum only when these issues don't even come to mind. Jan 29, 2013 at 15:41
3

Whether something is an enum and whether you know it at compile time are 2 separate issues. In the case where you do always know the values at compile time (even though it changes over releases), and it happens to be convenient to have it as some kind of explicitly typed object in your object oriented language and as a table in the DB, then I think code generating the object from the DB (or anything DRY - generating a DB script via reflection, generating DB script and object generation from something else...) is O.K.

Whether you should model that as an enum is a separate issue. Enums aren't very flexible when requirements change, so I would be wary.

You also say you don't want to redeploy. That seems like the enemy of explicitness. If the changes to your "enums" (or whatever they turn out to be) happen more often then your releases, then you really don't know the values at compile time. So you should get it from the DB, with or without caching based on the usual considerations.

5
  • 1
    I tend to not be a fan of code generation based on DB because this means building your system is explicitly dependent on correct deployment of the system existing, which can cause build errors and being that they're in automatically generated code, they're unlikely to be found before runtime. Sometimes it is the right solution I agree, but I think that's more rare than otherwise. Jan 28, 2013 at 22:45
  • 1
    @JimmyHoffa - If you end up with the same thing in the end, which place you designate as the source is a matter of convenience. But if you base it on the DB then you generally will put the data in the DB via some (source controlled) script. So usually filling the DB from your code is more convenient if a programmer is doing it.
    – psr
    Jan 29, 2013 at 1:07
  • Ah, I was referring to code generation from the database, going the other way and actually filling the database from the code is something I'm fine with; it relies on run-time realities that way rather than build-time prayers :) Jan 29, 2013 at 2:25
  • Currently I'm using T4 to generate the enums. I don't think adding fields to a dropdown ( what most of our lookup tables do) warrants a recompile and redepoly. That just seems silly.
    – nportelli
    Jan 29, 2013 at 14:00
  • 1
    @nportelli - As I said, it really only makes sense if the enums only change between releases.
    – psr
    Jan 29, 2013 at 17:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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