LSTANCZYK
9/26/2017 - 10:41 PM

Runtime Creates derived type and adds attributes

Runtime Creates derived type and adds attributes

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using FastDeepCloner;

namespace CHR.API.Provisioning.ATT.Web.Tests
{
    [SuppressMessage("ReSharper", "UnusedMember.Global")]
    public static class DerivedType
    {
        [SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
        public static Type CreateFrom<T>(HashSet<KeyValuePair<string, Attribute>> propertyAttributes) where T : class
        {
            var clonedType = DeepCloner.Clone(typeof(T));
            var clonerProperties = DeepCloner.GetFastDeepClonerProperties(clonedType);
            foreach (var propertyAttributeKeyvaluePair in propertyAttributes)
            {
                var propertyName = propertyAttributeKeyvaluePair.Key;
                var propertyAttirbute = propertyAttributeKeyvaluePair.Value;
                clonerProperties.First(p => p.Name == propertyName).Attributes.Add(propertyAttirbute);
            }

            return clonedType;
        }

        [SuppressMessage("ReSharper", "UnusedMember.Global")]
        public static object ActivateObjectFrom<T>(HashSet<KeyValuePair<string, Attribute>> propertyAttributes, object sourceObject = null) where T : class
        {
            object clonedType = CreateFrom<T>(propertyAttributes);
            var clonerProperties = DeepCloner.GetFastDeepClonerProperties(clonedType.GetType());
            foreach (var propertyAttributeKeyvaluePair in propertyAttributes)
            {
                var propertyName = propertyAttributeKeyvaluePair.Key;
                var propertyAttirbute = propertyAttributeKeyvaluePair.Value;
                clonerProperties.First(p => p.Name == propertyName).Attributes.Add(propertyAttirbute);
            }
            var instance = DeepCloner.CreateInstance(clonedType.GetType());
            if (sourceObject != null)
            {
                foreach (var propertyInfo in sourceObject.GetType().GetProperties(BindingFlags.GetProperty))
                {
                    var propertyValue = propertyInfo.GetValue(sourceObject);
                    var propertyName = propertyInfo.Name;
                    instance.GetType().GetProperty(propertyName)?.SetValue(instance, propertyValue);
                }
            }
            return instance;
        }
    }
}