0

I have a form where I collect data from users. When this data is collected, I pass it to various partners, however each partner has their own rules for each piece of data, so this has to be converted. I can make this happen, but my worries are about the robustness. Here's some code:

First, I have an enum. This is mapped to dropdown a dropdown list - the description is the text value, and the int mapped to the value.

public enum EmploymentStatusType
{
    [Description("INVALID!")]
    None = 0,
    [Description("Permanent full-time")]
    FullTime = 1,
    [Description("Permanent part-time")]
    PartTime = 2,
    [Description("Self employed")]
    SelfEmployed = 3
}

When the form is submitted, the selected value is converted to its proper type and stored in another class - the property looks like this:

    protected virtual EmploymentStatusType EmploymentStatus
    {
        get { return _application.EmploymentStatus; }
    }

For the final bit of the jigsaw, I convert the value to the partners required string value:

    Dictionary<EmploymentStatusType, string> _employmentStatusTypes;
    Dictionary<EmploymentStatusType, string> EmploymentStatusTypes
    {
        get
        {
            if (_employmentStatusTypes.IsNull())
            {
                _employmentStatusTypes = new Dictionary<EmploymentStatusType, string>()
                {
                    { EmploymentStatusType.FullTime, "Full Time" },
                    { EmploymentStatusType.PartTime, "Part Time" },
                    { EmploymentStatusType.SelfEmployed, "Self Employed" }
                };
            }

            return _employmentStatusTypes;
        }
    }

    string PartnerEmploymentStatus
    {
        get { return _employmentStatusTypes.GetValue(EmploymentStatus); }
    }

I call PartnerEmploymentStatus, which then returns the final output string.

Any ideas how this can be made more robust?

dotnetnoob
  • 10,783
  • 20
  • 57
  • 103
  • 3
    What is "non-robust" in your opinion? – Uwe Keim May 15 '13 at 09:57
  • The concern I have is that if/when the enums change/grow - and it is possible because new partners may have different rules that need to be accomodated, then all the other classes contain the mappings need to be changed and rested. If I have 30 partners this could become a big task. – dotnetnoob May 15 '13 at 10:15
  • 1
    Then you need to refactor it into one translation area. Coudl be something like a visitor pattern implementation. Your choices are distribute the code (as you are doing now) or visitor which would centralize it. You need to build in a degree of fragility so your covering tests will show problems when you extend in order to force you to maintain the code properly. You are in a fairly common quandry which is really a code organisational one. – John Nicholas May 15 '13 at 16:26
  • @JohnNicholas - Thanks for the visitor pattern advice - looked it up and this is exactly what I'm doing. Sometimes assurance is the right answer. – dotnetnoob May 16 '13 at 07:28
  • well ill make it an answer then ;p Agreed about assurance, i am finding more and more of my questions on here are simply testing my own sanity against others. 'Hi i have a question that i think has no answer, can someone give me an answer that somehow helps me please?' – John Nicholas May 23 '13 at 12:56

2 Answers2

3

Then you need to refactor it into one translation area. Could be something like a visitor pattern implementation. Your choices are distribute the code (as you are doing now) or visitor which would centralize it. You need to build in a degree of fragility so your covering tests will show problems when you extend in order to force you to maintain the code properly. You are in a fairly common quandry which is really a code organisational one

John Nicholas
  • 4,778
  • 4
  • 31
  • 50
1

I did encounter such a problem in one of my projects and I solved it by using a helper function and conventions for resource names.

The function is this one:

    public static Dictionary<T, string> GetEnumNamesFromResources<T>(ResourceManager resourceManager, params T[] excludedItems)
    {
        Contract.Requires(resourceManager != null, "resourceManager is null.");

        var dictionary =
            resourceManager.GetResourceSet(culture: CultureInfo.CurrentUICulture, createIfNotExists: true, tryParents: true)
            .Cast<DictionaryEntry>()
            .Join(Enum.GetValues(typeof(T)).Cast<T>().Except(excludedItems),
                de => de.Key.ToString(),
                v => v.ToString(),
                (de, v) => new
                {
                    DictionaryEntry = de,
                    EnumValue = v
                })
            .OrderBy(x => x.EnumValue)
            .ToDictionary(x => x.EnumValue, x => x.DictionaryEntry.Value.ToString());
        return dictionary;
    }

The convention is that in my resource file I will have properties that are the same as enum values (in your case None, PartTime etc). This is needed to perform the Join in the helper function which, you can adjust to match your needs.

So, whenever I want a (localized) string description of an enum value I just call:

var dictionary = EnumUtils.GetEnumNamesFromResources<EmploymentStatusType>(ResourceFile.ResourceManager);
var value = dictionary[EmploymentStatusType.Full];
RePierre
  • 9,358
  • 2
  • 20
  • 37