Example #1
0
        static TinyMapper()
        {
            IDynamicAssembly assembly = DynamicAssemblyBuilder.Get();

            _targetMapperBuilder = new TargetMapperBuilder(assembly);
            _config = new TinyMapperConfig(_targetMapperBuilder);
        }
Example #2
0
 public CKTypeCollector(IActivityMonitor monitor,
                        IServiceProvider serviceProvider,
                        IDynamicAssembly tempAssembly,
                        Func <IActivityMonitor, Type, bool>?typeFilter = null,
                        IEnumerable <string>?names = null)
 {
     Throw.CheckNotNullArgument(monitor);
     Throw.CheckNotNullArgument(serviceProvider);
     Throw.CheckNotNullArgument(tempAssembly);
     _monitor              = monitor;
     _typeFilter           = typeFilter ?? ((m, type) => type.FullName != null);
     _tempAssembly         = tempAssembly;
     _serviceProvider      = serviceProvider;
     _assemblies           = new HashSet <Assembly>();
     _objectCollector      = new Dictionary <Type, RealObjectClassInfo?>();
     _regularTypeCollector = new Dictionary <Type, TypeAttributesCache?>();
     _roots             = new List <RealObjectClassInfo>();
     _serviceCollector  = new Dictionary <Type, AutoServiceClassInfo>();
     _serviceRoots      = new List <AutoServiceClassInfo>();
     _serviceInterfaces = new Dictionary <Type, AutoServiceInterfaceInfo?>();
     _multipleMappings  = new Dictionary <Type, MultipleImpl>();
     KindDetector       = new CKTypeKindDetector(typeFilter);
     _pocoRegistrar     = new PocoRegistrar((m, t) => (KindDetector.GetValidKind(m, t) & CKTypeKind.IsPoco) != 0, typeFilter: _typeFilter);
     _names             = names == null || !names.Any() ? new[] { String.Empty } : names.ToArray();
 }
        public TargetMapperBuilder(IDynamicAssembly assembly)
        {
            Assembly = assembly;

            _classMapperBuilder = new ClassMapperBuilder(this);
            _collectionMapperBuilder = new CollectionMapperBuilder(this);
            _convertibleTypeMapperBuilder = new ConvertibleTypeMapperBuilder(this);
        }
Example #4
0
        public TargetMapperBuilder(IDynamicAssembly assembly)
        {
            Assembly = assembly;

            _classMapperBuilder           = new ClassMapperBuilder(this);
            _collectionMapperBuilder      = new CollectionMapperBuilder(this);
            _convertibleTypeMapperBuilder = new ConvertibleTypeMapperBuilder(this);
        }
        public TargetMapperBuilder(IDynamicAssembly assembly)
        {
            Assembly = assembly;

            _classMapperBuilder           = new ClassMapperBuilder(this);
            _collectionMapperBuilder      = new CollectionMapperBuilder(this);
            _convertibleTypeMapperBuilder = new ConvertibleTypeMapperBuilder(this);
            _customTypeMapperBuilder      = new CustomTypeMapperBuilder(this);

            NameMatching = DefaultNameMatching;
        }
Example #6
0
        /// <summary>
        /// Gets a type name in the same namespace as the provided type.
        /// This method is idempotent, it simply ensures that the returned name ends with "_CK":
        /// it can safely be called on the generated Stub type itself.
        /// </summary>
        /// <param name="this">This Dynamic assembly.</param>
        /// <param name="type">The base or stub type.</param>
        /// <returns>The stub or generated type name.</returns>
        public static string GetAutoImplementedTypeName(this IDynamicAssembly @this, Type type)
        {
            var n = type.FullName;

            if (String.IsNullOrEmpty(n))
            {
                throw new ArgumentException($"Type '{type}' doesn't have a FullName.");
            }
            n = n.Replace('+', '_');
            return(n.EndsWith("_CK", StringComparison.Ordinal) ? n : n + "_CK");
        }
Example #7
0
        public TinyMapper(IEnumerable <IObjectMapperBuilder> builders)
        {
            this._lock = new object();
            _mappers   = new Dictionary <TypePair, Mapper>();
            IDynamicAssembly assembly = DynamicAssemblyBuilder.Get();

            _targetMapperBuilder = new TargetMapperBuilder(assembly);
            _config = new TinyMapperConfig(_targetMapperBuilder);
            foreach (var builder in builders)
            {
                builder.Build(this);
            }
        }
Example #8
0
        Result?CreateResult(IDynamicAssembly assembly, IActivityMonitor monitor)
        {
            Result r            = new Result();
            bool   hasNameError = false;

            foreach (var signature in _result)
            {
                var cInfo = CreateClassInfo(assembly, monitor, signature);
                if (cInfo == null)
                {
                    return(null);
                }
                r.Roots.Add(cInfo);

                foreach (var i in signature)
                {
                    Type iCreate = typeof(IPocoFactory <>).MakeGenericType(i);
                    var  iInfo   = new InterfaceInfo(cInfo, i, iCreate);
                    cInfo.Interfaces.Add(iInfo);
                    r.AllInterfaces.Add(i, iInfo);
                }
                cInfo.OtherInterfaces.Remove(typeof(IPoco));
                cInfo.OtherInterfaces.Remove(typeof(IClosedPoco));
                foreach (var t in signature)
                {
                    cInfo.OtherInterfaces.Remove(t);
                }
                foreach (var e in cInfo.OtherInterfaces)
                {
                    IReadOnlyList <IPocoRootInfo>?value;
                    if (r.OtherInterfaces.TryGetValue(e, out value))
                    {
                        ((List <PocoRootInfo>)value).Add(cInfo);
                    }
                    else
                    {
                        r.OtherInterfaces.Add(e, new List <PocoRootInfo>()
                        {
                            cInfo
                        });
                    }
                }

                hasNameError |= !cInfo.InitializeNames(monitor);
            }
            return(hasNameError ||
                   !r.CheckPropertiesVarianceAndInstantiationCycleError(monitor) ||
                   !r.BuildNameIndex(monitor)
                   ? null
                   : r);
        }
Example #9
0
        /// <summary>
        /// Gets or creates the <see cref="ITypeScope"/> builder from an interface, the direct base type or from
        /// an already stub type that is named with <see cref="GetAutoImplementedTypeName(IDynamicAssembly, Type)"/> (its
        /// name ends with "_CK").
        /// <para>
        /// Public constructors of the <see cref="Type.BaseType"/> if it exists are automatically replicated: protected
        /// constructors are to be called by generated code if needed.
        /// </para>
        /// </summary>
        /// <param name="this">This Dynamic assembly.</param>
        /// <param name="monitor">The monitor to use.</param>
        /// <param name="type">The base or stub type. Can be an interface.</param>
        /// <param name="created">True if the type scope has been created. False if it was already defined.</param>
        /// <returns>Th generated class builder.</returns>
        public static ITypeScope FindOrCreateAutoImplementedClass(this IDynamicAssembly @this, IActivityMonitor monitor, Type type, out bool created)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }
            Type?  baseType;
            string name = type.Name;

            if (name.EndsWith("_CK", StringComparison.Ordinal))
            {
                baseType = type.BaseType;
            }
            else
            {
                baseType = type;
                name    += "_CK";
            }
            var ns = @this.Code.Global.FindOrCreateNamespace(type.Namespace ?? String.Empty);

            ITypeScope?tB = ns.FindType(name);

            if (created = (tB == null))
            {
                monitor.Trace($"Creating ITypeScope builder for class: '{ns.FullName}.{name}'.");
                tB = ns.CreateType("internal class " + name);
                if (baseType != null)
                {
                    if (baseType != typeof(object))
                    {
                        tB.Definition.BaseTypes.Add(new ExtendedTypeName(baseType.ToCSharpName()));
                        // Only public constructors are replicated: protected constructors are to be called
                        // by generated code.
                        tB.CreatePassThroughConstructors(baseType, ctor => ctor.IsPublic ? "public " : null);
                    }
                }
                else if (type.IsInterface)
                {
                    tB.Definition.BaseTypes.Add(new ExtendedTypeName(type.ToCSharpName()));
                }
            }
            return(tB !);
        }
Example #10
0
 /// <summary>
 /// Gets all information related to Poco support.
 /// This is never null: if an error occurred, <see cref="EmptyPocoSupportResult.Default"/> is used.
 /// Note that if no error but no Poco have been found, an empty result is produced that will not be
 /// the <see cref="EmptyPocoSupportResult.Default"/> instance.
 /// </summary>
 /// <param name="this">This Dynamic assembly.</param>
 /// <returns>The Poco information.</returns>
 public static IPocoSupportResult GetPocoSupportResult(this IDynamicAssembly @this) => (IPocoSupportResult)@this.Memory[typeof(IPocoSupportResult)] !;
Example #11
0
 protected MapperBuilder(IMapperBuilderConfig config)
 {
     _config   = config;
     _assembly = config.Assembly;
 }
Example #12
0
 protected MapperBuilder(IMapperBuilderConfig config)
 {
     _config = config;
     _assembly = config.Assembly;
 }
        static void Main()
        {
            Program.UsingCodeDOM();

            String          assemblyName  = "RVJ.Core.Person";
            IDynamicBuilder personBuilder = new DynamicBuilder(assemblyName);


            /*
             *
             *          Defines a dynamic .NET Assembly.
             *          The method automatically defines a dynamic .NET Module with the same name.
             *
             */
            IDynamicAssembly personDynamicAssembly = personBuilder.DefineDynamicAssembly();

            /*
             *
             *          Defines a dynamic .NET Module.
             *
             */

            IDynamicModule personDynamicModule = personDynamicAssembly.DefineDynamicModule();

            /*
             *
             *          Defines a dynamic .NET Type.
             *
             */

            IDynamicType personDynamicType = personDynamicModule.DefineDynamicType(assemblyName, ClassTypeFlags.Public, typeof(System.Object));


            IDynamicField _id_DynamicField   = personDynamicType.DefineDynamicField("_id", typeof(System.UInt32), FieldFlags.Private);
            IDynamicField _name_DynamicField = personDynamicType.DefineDynamicField("_name", typeof(System.String), FieldFlags.Private);
            IDynamicField _age_DynamicField  = personDynamicType.DefineDynamicField("_age", typeof(System.UInt32), FieldFlags.Private);

            /*
             *
             *          A dynamic .NET Property is associated with a dynamic .NET Field.
             *          By default, the implementation of IDynamicField.DefineDynamicProperty method defines both, get  and set accessor methods.
             *          We should use RVJ.Core.PropertyFlags enum option to indicates if characteristics of a dynamic .NET Property.
             *
             */

            _id_DynamicField.DefineDynamicProperty("Id", typeof(System.UInt32), PropertyFlags.Public | PropertyFlags.ReadAndWrite);
            _name_DynamicField.DefineDynamicProperty("Name", typeof(System.String), PropertyFlags.Public | PropertyFlags.ReadAndWrite);
            _age_DynamicField.DefineDynamicProperty("Age", typeof(System.UInt32), PropertyFlags.Public | PropertyFlags.ReadAndWrite);

            /*
             *
             *          Creates an instance of the RVJ.Core.Person dynamic .NET Type.
             *
             */

            Object person = personDynamicType.CreateAnInstance("RVJ.Core.Person");


            /*
             *
             *          Gets an instance of a dynamic .NET Field.
             *          The search that the System.Type.GetField() instance method does, is case-sensitive.
             *
             */
            Type personType = person.GetType();

            FieldInfo personFieldId   = personType.GetField("_id", (BindingFlags.NonPublic | BindingFlags.Instance));
            FieldInfo personFieldName = personType.GetField("_name", (BindingFlags.NonPublic | BindingFlags.Instance));
            FieldInfo personFieldAge  = personType.GetField("_age", (BindingFlags.NonPublic | BindingFlags.Instance));

            /*
             *
             *          Shows the dynamic .NET Field values before assigning new values.
             *
             */


            UInt32 newId   = ( UInt32 )personFieldId.GetValue(person);
            String newName = ( String )personFieldName.GetValue(person);
            UInt32 newAge  = ( UInt32 )personFieldAge.GetValue(person);

            if (newName == null)
            {
                newName = String.Empty;
            }

            Console.WriteLine("Before new values...\nperson._id: {0}\nperson._name: {1}\nperson._age: {2}\n", newId.ToString(), newName, newAge.ToString());

            newId   = 100;
            newName = "New Name!!!";
            newAge  = 25;

            personFieldId.SetValue(person, newId);
            personFieldName.SetValue(person, newName);
            personFieldAge.SetValue(person, newAge);


            newId   = ( UInt32 )personFieldId.GetValue(person);
            newName = ( String )personFieldName.GetValue(person);
            newAge  = ( UInt32 )personFieldAge.GetValue(person);

            Console.WriteLine("After new values assigned...\nperson._id: {0}\nperson._name: {1}\nperson._age: {2}\n", newId.ToString(), newName, newAge.ToString());


            Program.Pause();

            /*
             *
             *          Now, we are using the dynamic .NET Properties defined for each dynamic .NET Field, to do the same operations of "get" and "set" values.
             *
             */

            newId   = ( UInt32 )personType.InvokeMember("Id", BindingFlags.GetProperty, null, person, null);
            newName = ( String )personType.InvokeMember("Name", BindingFlags.GetProperty, null, person, null);
            newAge  = ( UInt32 )personType.InvokeMember("Age", BindingFlags.GetProperty, null, person, null);


            Console.WriteLine("Before new values assigned...\nperson._id: {0}\nperson._name: {1}\nperson._age: {2}\n", newId.ToString(), newName, newAge.ToString());



            newId   = 200;
            newName = "New Name using a dynamic .NET Property!!!";
            newAge  = 35;

            personType.InvokeMember("Id", BindingFlags.SetProperty, null, person, new Object[] { newId });
            personType.InvokeMember("Name", BindingFlags.SetProperty, null, person, new Object[] { newName });
            personType.InvokeMember("Age", BindingFlags.SetProperty, null, person, new Object[] { newAge });

            Console.WriteLine("After new values...\nperson._id: {0}\nperson._name: {1}\nperson._age: {2}\n", newId.ToString(), newName, newAge.ToString());

            Program.Pause(true);
        }
Example #14
0
        static PocoRootInfo?CreateClassInfo(IDynamicAssembly assembly, IActivityMonitor monitor, IReadOnlyList <Type> interfaces)
        {
            // The first interface is the PrimartyInterface: we use its name to drive the implementation name.
            string pocoTypeName = assembly.GetAutoImplementedTypeName(interfaces[0]);
            var    moduleB      = assembly.StubModuleBuilder;
            var    tB           = moduleB.DefineType(pocoTypeName);

            // The factory also ends with "_CK": it is a generated type.
            var tBF = moduleB.DefineType(pocoTypeName + "Factory_CK");

            // The IPocoFactory base implementation.
            tBF.AddInterfaceImplementation(typeof(IPocoFactory));
            {
                MethodBuilder m = tBF.DefineMethod("get_PocoDirectory", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Final, typeof(PocoDirectory), Type.EmptyTypes);
                ILGenerator   g = m.GetILGenerator();
                g.Emit(OpCodes.Ldnull);
                g.Emit(OpCodes.Ret);
                var p = tBF.DefineProperty(nameof(IPocoFactory.PocoDirectory), PropertyAttributes.None, typeof(PocoDirectory), null);
                p.SetGetMethod(m);
            }
            {
                MethodBuilder m = tBF.DefineMethod("get_PocoClassType", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Final, typeof(Type), Type.EmptyTypes);
                ILGenerator   g = m.GetILGenerator();
                g.Emit(OpCodes.Ldtoken, tB);
                g.Emit(OpCodes.Call, _typeFromToken);
                g.Emit(OpCodes.Ret);
                var p = tBF.DefineProperty(nameof(IPocoFactory.PocoClassType), PropertyAttributes.None, typeof(Type), null);
                p.SetGetMethod(m);
            }
            {
                MethodBuilder m = tBF.DefineMethod("get_Name", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Final, typeof(string), Type.EmptyTypes);
                ILGenerator   g = m.GetILGenerator();
                g.Emit(OpCodes.Ldnull);
                g.Emit(OpCodes.Ret);
                var p = tBF.DefineProperty(nameof(IPocoFactory.Name), PropertyAttributes.None, typeof(string), null);
                p.SetGetMethod(m);
            }
            {
                MethodBuilder m = tBF.DefineMethod("get_PreviousNames", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Final, typeof(IReadOnlyList <string>), Type.EmptyTypes);
                ILGenerator   g = m.GetILGenerator();
                g.Emit(OpCodes.Ldnull);
                g.Emit(OpCodes.Ret);
                var p = tBF.DefineProperty(nameof(IPocoFactory.PreviousNames), PropertyAttributes.None, typeof(IReadOnlyList <string>), null);
                p.SetGetMethod(m);
            }
            {
                MethodBuilder m = tBF.DefineMethod("get_Interfaces", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Final, typeof(IReadOnlyList <Type>), Type.EmptyTypes);
                ILGenerator   g = m.GetILGenerator();
                g.Emit(OpCodes.Ldnull);
                g.Emit(OpCodes.Ret);
                var p = tBF.DefineProperty(nameof(IPocoFactory.Interfaces), PropertyAttributes.None, typeof(IReadOnlyList <Type>), null);
                p.SetGetMethod(m);
            }
            {
                MethodBuilder m = tBF.DefineMethod("Create", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.Final, typeof(IPoco), Type.EmptyTypes);
                ILGenerator   g = m.GetILGenerator();
                g.Emit(OpCodes.Ldnull);
                g.Emit(OpCodes.Ret);
            }

            // The IPocoGeneratedClass implementation.
            var properties   = new Dictionary <string, PocoPropertyInfo>();
            var propertyList = new List <PocoPropertyInfo>();
            List <PropertyInfo>?externallyImplementedPropertyList = null;

            // This is required to handle "non actual Poco" (CKTypeDefiner "base type"): interfaces list
            // contains only actual IPoco, the expanded set contains the closure of all the interfaces.
            //
            // This work is the perfect opportunity to handle the "closed poco" feature without overhead:
            // by identifying the "biggest" interface in terms of base interfaces, we can check that it
            // actually closes the whole IPoco.
            //
            var  expanded     = new HashSet <Type>(interfaces);
            Type?closure      = null;
            int  maxICount    = 0;
            bool mustBeClosed = false;

            foreach (var i in interfaces)
            {
                mustBeClosed |= typeof(IClosedPoco).IsAssignableFrom(i);
                var bases = i.GetInterfaces();
                if (closure == null || maxICount < bases.Length)
                {
                    maxICount = bases.Length;
                    closure   = i;
                }
                expanded.AddRange(bases);
                // Since we are iterating over the IPoco interfaces, we can build
                // the factory class that must support all the IPocoFactory<>.
                Type iCreate = typeof(IPocoFactory <>).MakeGenericType(i);
                tBF.AddInterfaceImplementation(iCreate);
                {
                    MethodBuilder m = tBF.DefineMethod("C" + expanded.Count.ToString(System.Globalization.NumberFormatInfo.InvariantInfo), MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.Final, i, Type.EmptyTypes);
                    ILGenerator   g = m.GetILGenerator();
                    g.Emit(OpCodes.Ldnull);
                    g.Emit(OpCodes.Ret);
                    tBF.DefineMethodOverride(m, iCreate.GetMethod(nameof(IPocoFactory <IPoco> .Create)) !);
                }
            }
            // If the IClosedPoco has been found, we ensure that a closure interface has been found.
            if (mustBeClosed)
            {
                Debug.Assert(maxICount < expanded.Count);
                if (maxICount < expanded.Count - 1)
                {
                    monitor.Error($"Poco family '{interfaces.Select( b => b.ToCSharpName() ).Concatenate("', '")}' must be closed but none of these interfaces covers the other ones.");
                    return(null);
                }
                Debug.Assert(closure != null, "Since there is at least one interface.");
                monitor.Debug($"{closure.FullName}: IClosedPoco for {interfaces.Select( b => b.ToCSharpName() ).Concatenate()}.");
            }
            // Supports the IPocoGeneratedClass interface.
            tB.AddInterfaceImplementation(typeof(IPocoGeneratedClass));
            {
                MethodBuilder m = tB.DefineMethod("get_Factory", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Final, typeof(IPocoFactory), Type.EmptyTypes);
                ILGenerator   g = m.GetILGenerator();
                g.Emit(OpCodes.Ldnull);
                g.Emit(OpCodes.Ret);
                var p = tB.DefineProperty(nameof(IPocoGeneratedClass.Factory), PropertyAttributes.None, typeof(IPocoFactory), null);
                p.SetGetMethod(m);
            }

            // For each expanded interfaces (all of them: the Interfaces and the OtherInterfaces):
            // - Implements the interface on the PocoClass (tB).
            // - Registers the properties and creates the PocoPropertyInfo.
            bool hasPropertyError = false;

            foreach (var i in expanded)
            {
                tB.AddInterfaceImplementation(i);

                // Analyzing interface properties.
                // For union types, the UnionTypes nested struct fields are cached once.
                PropertyInfo[]? unionTypesDef = null;

                foreach (var p in i.GetProperties())
                {
                    // As soon as a property claims to be implemented, we remove it from the properties.
                    if (p.GetCustomAttributesData().Any(d => d.AttributeType.Name == nameof(AutoImplementationClaimAttribute)))
                    {
                        if (externallyImplementedPropertyList == null)
                        {
                            externallyImplementedPropertyList = new List <PropertyInfo>();
                        }
                        externallyImplementedPropertyList.Add(p);
                        if (properties.TryGetValue(p.Name, out var implP))
                        {
                            propertyList.RemoveAt(implP.Index);
                            for (int idx = implP.Index; idx < propertyList.Count; ++idx)
                            {
                                --propertyList[idx].Index;
                            }
                        }
                    }
                    else
                    {
                        hasPropertyError &= HandlePocoProperty(monitor, expanded, properties, propertyList, ref unionTypesDef, i, p);
                    }
                }
            }
            if (hasPropertyError)
            {
                return(null);
            }

            // Implements the stubs for each externally implemented property.
            if (externallyImplementedPropertyList != null)
            {
                foreach (var p in externallyImplementedPropertyList)
                {
                    EmitHelper.ImplementStubProperty(tB, p, isVirtual: false, alwaysImplementSetter: false);
                }
            }

            // Handles default values and implements the stubs for each
            // PocoPropertyInfo.
            foreach (var p in propertyList)
            {
                if (!InitializeDefaultValue(p, monitor))
                {
                    return(null);
                }

                if (p.IsReadOnly && p.DefaultValueSource != null)
                {
                    monitor.Error($"Read only {p} cannot have a default value attribute: [DefaultValue( {p.DefaultValueSource} )].");
                    return(null);
                }
                foreach (var propInfo in p.DeclaredProperties)
                {
                    EmitHelper.ImplementStubProperty(tB, propInfo, isVirtual: false);
                }
            }

            var tPoCo = tB.CreateType();

            Debug.Assert(tPoCo != null);

            var tPocoFactory = tBF.CreateType();

            Debug.Assert(tPocoFactory != null);

            return(new PocoRootInfo(tPoCo, tPocoFactory, mustBeClosed, closure, expanded, properties, propertyList, externallyImplementedPropertyList));
        }
Example #15
0
 public IPocoSupportResult?Finalize(IDynamicAssembly assembly, IActivityMonitor monitor)
 {
     return(CreateResult(assembly, monitor));
 }
Example #16
0
 /// <summary>
 /// Gets or creates the <see cref="ITypeScope"/> builder from an interface, the direct base type or from
 /// an already stub type that is named with <see cref="GetAutoImplementedTypeName(IDynamicAssembly, Type)"/> (its
 /// name ends with "_CK").
 /// <para>
 /// Public constructors of the <see cref="Type.BaseType"/> if it exists are automatically replicated: protected
 /// constructors are to be called by generated code if needed.
 /// </para>
 /// </summary>
 /// <param name="this">This Dynamic assembly.</param>
 /// <param name="monitor">The monitor to use.</param>
 /// <param name="type">The base or stub type. Can be an interface.</param>
 /// <returns>Th generated class builder.</returns>
 public static ITypeScope FindOrCreateAutoImplementedClass(this IDynamicAssembly @this, IActivityMonitor monitor, Type type) => FindOrCreateAutoImplementedClass(@this, monitor, type, out bool _);
        internal protected ImplementableTypeInfo?InitializeImplementableTypeInfo(IActivityMonitor monitor, IDynamicAssembly assembly)
        {
            Debug.Assert(Type.IsAbstract && assembly != null && !IsExcluded);

            if (_initializeImplementableTypeInfo)
            {
                return(ImplementableTypeInfo);
            }
            _initializeImplementableTypeInfo = true;

            var        combined = new List <ICKCustomAttributeProvider>();
            CKTypeInfo?p        = this;

            do
            {
                Debug.Assert(p.Attributes != null);
                combined.Add(p.Attributes);
                p = p.Generalization;
            }while(p != null);

            var autoImpl = ImplementableTypeInfo.CreateImplementableTypeInfo(monitor, Type, new CustomAttributeProviderComposite(combined));

            if (autoImpl != null && autoImpl.CreateStubType(monitor, assembly) != null)
            {
                return(ImplementableTypeInfo = autoImpl);
            }
            return(null);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="GlobalSearchAppDomainCreationResult"/> class.
 /// </summary>
 /// <param name="domain">App Domain.</param>
 /// <param name="assembly">Dynamic assembly.</param>
 public GlobalSearchAppDomainCreationResult(AppDomain domain, IDynamicAssembly assembly)
 {
     AppDomain = domain;
     DynamicAssembly = assembly;
 }
        static void Main()
        {
            System.Reflection.Emit.pro



            String          assemblyName  = "RVJ.Core.Person";
            IDynamicBuilder personBuilder = new DynamicBuilder(assemblyName);


            /*
             *
             * Defines a dynamic .NET Assembly.
             * The method automatically defines a dynamic .NET Module with the same name.
             *
             */
            IDynamicAssembly personDynamicAssembly = personBuilder.DefineDynamicAssembly();

            /*
             *
             * Defines a dynamic .NET Module.
             *
             */

            IDynamicModule personDynamicModule = personDynamicAssembly.DefineDynamicModule();

            /*
             *
             * Defines a dynamic .NET Type.
             *
             */

            IDynamicType personDynamicType = personDynamicModule.DefineDynamicType(assemblyName, ClassTypeFlags.Public, typeof(System.Object));


            personDynamicType.DefineDynamicField("_id", typeof(System.UInt32), FieldFlags.Private);
            personDynamicType.DefineDynamicField("_name", typeof(System.String), FieldFlags.Private);
            personDynamicType.DefineDynamicField("_age", typeof(System.UInt32), FieldFlags.Private);

            /*
             *
             * Creates an instance of the RVJ.Core.Person dynamic .NET Type.
             *
             */

            Object person = personDynamicType.CreateAnInstance("RVJ.Core.Person");


            /*
             *
             * Gets an instance of a dynamic .NET Field.
             * The search that the System.Type.GetGetField() instance method does, is case-sensitive.
             *
             */
            Type      personType      = person.GetType();
            FieldInfo personFieldId   = personType.GetField("_id", (BindingFlags.NonPublic | BindingFlags.Instance));
            FieldInfo personFieldName = personType.GetField("_name", (BindingFlags.NonPublic | BindingFlags.Instance));
            FieldInfo personFieldAge  = personType.GetField("_age", (BindingFlags.NonPublic | BindingFlags.Instance));

            /*
             *
             * Shows the dynamic .NET Field values before assigning new values.
             *
             */


            UInt32 newId   = ( UInt32 )personFieldId.GetValue(person);
            String newName = ( String )personFieldName.GetValue(person);
            UInt32 newAge  = ( UInt32 )personFieldAge.GetValue(person);

            if (newName == null)
            {
                newName = String.Empty;
            }

            Console.WriteLine("Before new values...\nperson._id: {0}\nperson._name: {1}\nperson._age: {2}\n", newId.ToString(), newName, newAge.ToString());

            newId   = 100;
            newName = "New Name!!!";
            newAge  = 25;

            personFieldId.SetValue(person, newId);
            personFieldName.SetValue(person, newName);
            personFieldAge.SetValue(person, newAge);


            newId   = ( UInt32 )personFieldId.GetValue(person);
            newName = ( String )personFieldName.GetValue(person);
            newAge  = ( UInt32 )personFieldAge.GetValue(person);

            Console.WriteLine("After new values assigned...\nperson._id: {0}\nperson._name: {1}\nperson._age: {2}\n", newId.ToString(), newName, newAge.ToString());

            Console.ReadLine();
            Console.WriteLine("Press <ENTER> to finish...");
        }