public TypeConstructor()
            {
                var interfaceType = typeof(IMetrics);
                var typeBuilder   = ModuleBuilder.DefineType("GenericMetrics", TypeAttributes.Public | TypeAttributes.Sealed);

                typeBuilder.AddInterfaceImplementation(interfaceType);

                this.Properties = this.HandleProperties(typeBuilder, interfaceType);

                try
                {
                    this.Type = typeBuilder.CreateTypeInfo().AsType();
                }
                catch (TypeLoadException e)
                {
                    throw new Exception($"Unable to create implementation for interface {interfaceType.FullName}", e);
                }
            }
            private PropertyGrouping HandleProperties(TypeBuilder typeBuilder, Type interfaceType)
            {
                var grouping = new PropertyGrouping(InterfaceAndChildren(interfaceType, x => x.GetTypeInfo().GetProperties()));
                MethodAttributes attributes = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.SpecialName;

                foreach (var property in grouping.Metric)
                {
                    var propertyBuilder = typeBuilder.DefineProperty(property.PropertyInfo.Name, PropertyAttributes.None, property.PropertyInfo.PropertyType, null);
                    var getter          = typeBuilder.DefineMethod(property.PropertyInfo.GetMethod.Name, attributes, property.PropertyInfo.PropertyType, new Type[0]);
                    var backingField    = typeBuilder.DefineField("bk_" + property.PropertyInfo.Name, property.PropertyInfo.PropertyType, FieldAttributes.Private);

                    var getterIlGenerator = getter.GetILGenerator();
                    getterIlGenerator.Emit(OpCodes.Ldarg_0);
                    getterIlGenerator.Emit(OpCodes.Ldfld, backingField);
                    getterIlGenerator.Emit(OpCodes.Ret);
                    propertyBuilder.SetGetMethod(getter);

                    property.BackingField = backingField;
                }

                return(grouping);
            }