Creating user friendly strings for C# enums

Standard

Recently one of my colleague asked me question, he want to create a enum with string values. But C# doesn’t support string based enums, so here is the code snippet which will help you to associate string values to enums. This code is not using any custom attribute, instead it is using DescriptionAttribute class. Here is the enum, with the associated string values.

enum OrderStatus
{
    [Description("New Order")]
    NewOrder = 1,
    [Description("Order is processing")]
    Processing = 2,
    [Description("Order is shipped")]
    Shipped = 3
}

And here is the extension method, which returns the string value associated to the enum

public static class Extensions
{
    public static string Description(this Enum @enum)
    {
        var description = string.Empty;
        var fields = @enum.GetType().GetFields();
        foreach (var field in fields)
        {
            var descriptionAttribute = Attribute.GetCustomAttribute(field,
                typeof(DescriptionAttribute)) as DescriptionAttribute;
            if (descriptionAttribute != null && 
field.Name.Equals(@enum.ToString(), StringComparison.InvariantCultureIgnoreCase))
            {
                description = descriptionAttribute.Description;
                break;
            }
        }

        return description;
    }
}

You can get the description from enum like this.

var orderStatus = OrderStatus.NewOrder;
Console.WriteLine(orderStatus.Description());

Happy Programming :)

Update : Based on the comment from NDVictory, source code modified to return the exact value, earlier it was always returning the first value. Thank you NDVictory

How to identify static class using reflection

Standard

Today someone asked me, how to find static class from list of types. I was against the implementation he was doing, but still I couldn’t find how to find static class. Later I did some research and I found like you need to look for IsAbstract and IsSealed properties of the type.

Here is source code, which identify the static class from the list of available types in the assembly.

class Program
{
    static void Main(string[] args)
    {
        var types = Assembly.GetExecutingAssembly().GetTypes();
        types.Where(x => x.IsAbstract && x.IsSealed).ToList()
            .ForEach(Console.WriteLine);
    }
}

static class StaticClass { }

sealed class SealedClass { }

interface Interface { }

class NormalClass { }

abstract class AbstractClass { }

If you run the above code, it will print the StaticClass name.

Happy Programming :)

Converting DataTable to Generic List<T>

Standard

Code snippet for converting a DataTable to Generic List<T>.

public static List<TEntity> ToList<TEntity>(this DataTable dataTable,
    Dictionary<string, string> mapping) where TEntity : new()
{
    var list = new List<TEntity>();
    foreach (DataRow dataRow in dataTable.Rows)
    {
        var entity = new TEntity();
        foreach (var keyvaluePair in mapping)
        {
            var property = entity.GetType().GetProperty(keyvaluePair.Key,
                            BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
            if (dataRow[keyvaluePair.Value] != DBNull.Value)
            {
                var propertyType = 
                    Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
                var value = 
                    Convert.ChangeType(dataRow[keyvaluePair.Value], propertyType);
                property.SetValue(entity, value, null);
            }
        }

        list.Add(entity);
    }

    return list;
}

You can use this as an extension method to the Data Table class. By providing the mapping dictionary, the consumer class can decide which all columns / properties need to participate in the conversion.

Happy Programming :)

Creating a WCF service proxy with ChannelFactory <T>

Standard

A proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate.(From wiki). In case of WCF, proxy class helps client application to use WCF service,without knowing the address or implementation details. Here is the code for generic WCF proxy, using ChannelFactory class. ChannelFactory enables you to dynamically creating a proxy object based on the Service Contract. It will help you to avoid update service references or proxies generated using svcutil utility.

internal sealed class GenericProxy<TContract> : IDisposable where TContract : class
{
    private ChannelFactory<TContract> _channelFactory;
    private TContract _channel;

    public GenericProxy()
    {
        _channelFactory = new ChannelFactory<TContract>();
    }

    public GenericProxy(Binding binding, EndpointAddress remoteAddress)
    {
        _channelFactory = new ChannelFactory<TContract>(binding, remoteAddress);
    }

    public void Execute(Action<TContract> action)
    {
        action.Invoke(Channel);
    }

    public TResult Execute<TResult>(Func<TContract, TResult> function)
    {
        return function.Invoke(Channel);
    }

    private TContract Channel
    {
        get
        {
            if (_channel == null)
            {
                _channel = _channelFactory.CreateChannel();
            }

            return _channel;
        }
    }

    public void Dispose()
    {
        try
        {
            if (_channel != null)
            {
                var currentChannel = _channel as IClientChannel;
                if (currentChannel.State == CommunicationState.Faulted)
                {
                    currentChannel.Abort();
                }
                else
                {
                    currentChannel.Close();
                }
            }
        }
        finally
        {
            _channel = null;
            GC.SuppressFinalize(this);
        }
    }
}

The IDisposable implementation will help developers to close / abort channel with “using” statement.

And you can use this like the following.

using (var proxy = new GenericProxy<ICalculator>())
{
    var result = proxy.Execute<int>(x => x.Add(1, 2));
    return result;
}

The code is invoking Add method of Calculator service. The EndPoint and Binding information will fetched from the app.config file.

Happy Programming :)