views:

152

answers:

3

I've defined an Enum as part of the model objects for an ASP.NET MVC application.

The Enum is called 'ContentTypes' and looks something like this:

public enum ContentTypes
{
    [Description("News story")]
    NewsStory = 1,

    [Description("Article")]
    Article = 2
}

Now I'm planning to add another set of attributes to the enum items called 'Route'. This attribute will allow me to map each ContentType to an URL that can handle it.

So after this I'll have:

public enum ContentTypes
{
    [Description("News story")]
    [Route("news/item/{URLName}")]
    NewsStory = 1,

    [Description("Article")]
    [Route("article/item/{URLName}")]
    Article = 2
}

Do you think the enum is getting too heavy-weight at this point?

Would it be better to break the enum items into, say, classes, and then give each class a 'Description' and 'Route' attribute?

+2  A: 

Personally, I think Enums should be kept simple. At the point where there become more than just a mnemonic, I would consider Fowler's "Replace Type Code with State/Strategy Pattern".

So, Yes, I would convert to a Class.

Mitch Wheat
+1  A: 

You can combine your attributes so it would look more like this:

[Description("x"), Route("y")]

if you think the syntax looks better. But I agree with Mitch, those might do better as classes, especially if there is a chance you may need to add another attribute in the future.

Yuriy Faktorovich
+8  A: 

You are really trying to use the Enum to differentiate multiple variations of the Content object, without going to the trouble of actually creating multiple versions of the Content object.

It's a good bet that the behavior of your application will depend on what the Enum is set to. For example you might have something like:

public Content
{
    private ContentTypes contentType;
    public string ToString()
    {
        switch (contentType)
        ...
    }
}

This will drive you crazy from a maintainability perspective. Consider instead using inheritance to get the behavior you are after:

public Content
{
    public abstract string ToString();
}

public NewsStory : Content
{
    public override string ToString() { /* Appropriate formatting of output */ }
}

public Article : Content
{
    public override string ToString() { /* Appropriate formatting of output */ }
}

Now to really get fancy (and use the Design-by-Contract approach), consider all of the things any Content would have in common and define an interface, e.g. IContent. If you do that, you can do things like:

List<IContent> myContent;
foreach (IContent ic in myContent) ic.ToString();
Eric J.