2

I have a two sets of Urls one for PreProd and one for Prod. Each Url has several API nodes. Instead of hard coding these API nodes, I maintain them in an enum

Something like this:

//Prod
private enum Prod
{
    precheckorder,
    submitresubmit,
    creditInquiry,
    createupdateorder,
    confirmorder,
    getorderstatus,
    cancelorder,
}

/// <summary>
/// Gets the relative URL.
/// </summary>
/// <param name="u">The u.</param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
private static string GetRelativeUrl(Prod u)
{
    switch (u)
    {
        case Prod.precheckorder:
            return "https://contesa.tex.com/api/precheckorder";
        case Prod.submitresubmit:
            return "https://contesa.tex.com/api/submitresubmit";
        case Prod.creditInquiry:
            return "https://contesa.tex.com/api/creditinquiry";
        case Prod.createupdateorder:
            return "https://contesa.tex.com/api/createupdateorder";
        case Prod.confirmorder:
            return "https://contesa.tex.com/api/confirmorder";
        case Prod.getorderstatus:
            return "https://contesa.tex.com/api/getorderstatus";
        case Prod.cancelorder:
            return "https://contesa.tex.com/api/cancelorder";
        default:
            // Handle bad URL, possibly throw
            throw new Exception();
    }
}

We use environment variables to store the Environment name and thats what dictates which API set to use.

Ideally, I would like to have a single method, I pass in my environment and api name and it will return the API Url.

Something like

GettexApiUrlBasedOnEnvironment("Dev", "precheckorder");

and response will be

"https://contoso.tex.com/api/precheckorder"

Any ideas/suggestions will be much appreciated. TIA

1
  • It's not clear what you're trying to do. If you're just trying to have a method return then just have two methods with an overload where the input parameter is the enum type and do the logic within the method (e.g. 'string MyMethod(EnumType1 en)' and 'string MyMethod(EnumType2 en)'). Also, I see the word "Dev" in the Gettex... method you show but not elsewhere in the question. Are you just trying to change the result based on whether you're running in release/debug mode? If so just use '#if DEBUG' and put some logic when the program loads. What is the 'reflection' tag for? Commented Mar 1, 2017 at 20:39

3 Answers 3

2

Just store your urls in one dictionary, like this:

public enum ApiType
{
    precheckorder,
    submitresubmit,
    creditInquiry,
    createupdateorder,
    confirmorder,
    getorderstatus,
    cancelorder,
}

 public enum EnvironmentType {
    Dev,
    Prod
}

public static string GettexApiUrl(ApiType apiType) {
    var envRaw = Environment.GetEnvironmentVariable("YourVariable");
    EnvironmentType env;
    if (!Enum.TryParse(envRaw, out env))
        throw new Exception("Invalid environment provided in environment variable YourVariable: " + envRaw);
    return GettexApiUrlBasedOnEnvironment(env, apiType);
}

public static string GettexApiUrlBasedOnEnvironment(EnvironmentType env, ApiType apiType) {
    if (!_urls.ContainsKey(env))
        throw new Exception("Invalid environment " + env);
    var url = _urls[env];
    if (!url.ContainsKey(apiType))
        throw new Exception("Invalid api type " + apiType);
    return url[apiType];
}

private static readonly Dictionary<EnvironmentType, Dictionary<ApiType, string>> _urls = new Dictionary<EnvironmentType, Dictionary<ApiType, string>>(
    ) {
    {EnvironmentType.Dev, new Dictionary<ApiType, string>() {
        {ApiType.precheckorder,  "https://contoso.tex.com/api/precheckorder"},
        // etc
    } }, {
        EnvironmentType.Prod, new Dictionary<ApiType, string>() { 
        {ApiType.precheckorder,  "https://contesa.tex.com/api/precheckorder"},
    }},
}; 
Sign up to request clarification or add additional context in comments.

Comments

1

You can also use reflection, and get the enum's type and value using a string representation like this:

using System;
using System.Reflection;

namespace EnumGames
{
    public class Program
    {
        static void Main(string[] args)
        {
            SomeClass sc = new SomeClass();
            var ans = sc.GetEnumValue("MyEnum", "OptionB");
        }
    }

    public class SomeClass
    {
        public enum MyEnum
        {
            OptionA,
            OptionB,
            OptionC
        }
        public enum MyOtherEnum
        {
            OptionA,
            OptionB,
            OptionC
        }
        public string GetEnumValue(string enumNameString, string enumOptionString)
        {
            var assembly = Assembly.GetExecutingAssembly();
            var enumType = assembly.GetType($"{this.ToString()}+{enumNameString}");
            var enumOption = Enum.Parse(enumType, enumOptionString);
            return GetEnumValue(enumOption);
        }
        private string GetEnumValue(object enumOption)
        {
            if (enumOption is MyEnum)
            {
                switch ((MyEnum)enumOption)
                {
                    case MyEnum.OptionA:
                        return "Hi";
                    case MyEnum.OptionB:
                        return "Hello";
                    case MyEnum.OptionC:
                        return "Yo";
                    default:
                        return "Nope";
                }
            }
            else if (enumOption is MyOtherEnum)
            {
                switch ((MyOtherEnum)enumOption)
                {
                    case MyOtherEnum.OptionA:
                        return "Bye";
                    case MyOtherEnum.OptionB:
                        return "Ta-Ta!";
                    case MyOtherEnum.OptionC:
                        return "Goodbye";
                    default:
                        return "Nopee";
                }
            }
            return "Nooope";
        }
    }
}

In the example above, GetEnumValue() receives the enum name and option, converts it to a real enum option and then uses another method to get the desired value.

So, by calling

GetEnumValue("MyEnum", "OptionB");

I will receive the string "Hello".

And by calling

GetEnumValue("MyOtherEnum", "OptionB");

I will receive the string "Ta-Ta!".

Comments

1

Try the code below, without the additional dictionaries, enums, switch\cases, etc.

private static string GettexApiUrlBasedOnEnvironment(string envType, string api)
{
            string env = envType.Equals("Dev") ? "contoso" : "contesa";
            return $"http://{env}.tex.com/api/{api}";
}

It is simple and no maintenance is needed in case of new API.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.