コード例 #1
0
        public Type EmitClass(IEnumerable <Type> interfaceTypes,
                              Type baseType,
                              IEnumerable <MethodInfo> methodsToOverride,
                              IEnumerable <PropertyInfo> propertiesToOverride,
                              IEnumerable <EventInfo> eventsToOverride,
                              ConstructorInfo baseConstructor,
                              IEnumerable <CustomAttributeBuilder> attributeBuilders)
        {
            // Apply default values for parameters

            if (baseType == null)
            {
                baseType = typeof(EmittedClassBase);
            }

            // Check limitations for this version

            if (baseType != typeof(EmittedClassBase))
            {
                throw new NotImplementedException("The only supported baseType value is 'EmittedClassBase' in this version.");
            }
            if ((interfaceTypes == null) || (interfaceTypes.Count() != 1))
            {
                throw new NotImplementedException(
                          "Current implementation should be provided with exactly one single interface to implement.");
            }

            Type interfaceType = interfaceTypes.Single();

            // Validate arguments

            if (!interfaceType.IsInterface)
            {
                throw new ArgumentException("interfaceTypes can contain 'interface' types only. " + interfaceType.FullName +
                                            " is not an interface.");
            }

            // Check if the component is initialized

            if ((_moduleBuilder == null) || (_assemblyBuilder == null))
            {
                throw new InvalidOperationException("The DefaultClassEmitter component is not initialized properly.");
            }

            var uniqueTypeNumber = Interlocked.Increment(ref _typeNumber);
            var typeName         = DynamicTypePrefix + interfaceType.Name + uniqueTypeNumber;

            var typeBuilder = _moduleBuilder.DefineType(
                typeName,
                TypeAttributes.Public
                | TypeAttributes.Class
                | TypeAttributes.AutoClass
                | TypeAttributes.AnsiClass
                | TypeAttributes.BeforeFieldInit
                | TypeAttributes.AutoLayout,
                typeof(EmittedClassBase),
                new[] { interfaceType });

            // Add custom attributes

            if (attributeBuilders != null)
            {
                foreach (var builder in attributeBuilders)
                {
                    typeBuilder.SetCustomAttribute(builder);
                }
            }

            // Implement properties, events and methods

            foreach (var propertyInfo in interfaceType.GetProperties())
            {
                PropertyEmitter.EmitProperty(typeBuilder, propertyInfo);
            }

            foreach (var eventInfo in interfaceType.GetEvents())
            {
                EventEmitter.EmitEvent(typeBuilder, eventInfo);
            }

            foreach (var methodInfo in interfaceType.GetMethods())
            {
                MethodBuilder methodBuilder = MethodEmitter.EmitMethod(
                    typeBuilder,
                    methodInfo.Name,
                    methodInfo.GetParameters().Select(pi => pi.ParameterType).ToArray(),
                    methodInfo.GetParameters().Select(pi => pi.IsOut).ToArray(),
                    methodInfo.ReturnType,
                    methodInfo.ReflectedType,
                    InterfaceMethodAttributes);

                typeBuilder.DefineMethodOverride(methodBuilder, methodInfo);
            }

            var result = typeBuilder.CreateTypeInfo();


//			if (SaveEmittedAssembly)
//				_assemblyBuilder.Save(DynamicAssemblyName + ".dll");

            return(result);
        }