//----------------------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace System.ServiceModel.ComIntegration { using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Reflection.Emit; using System.Runtime; using System.Runtime.InteropServices; using System.Threading; class EmitterCache { static EmitterCache Provider = null; static object initLock = new object(); internal static EmitterCache TypeEmitter { get { lock (initLock) { if (Provider == null) { EmitterCache localProvider = new EmitterCache(); Thread.MemoryBarrier(); Provider = localProvider; } } if (Provider == null) { throw Fx.AssertAndThrowFatal("Provider should not be null"); } return Provider; } } ModuleBuilder DynamicModule; AssemblyBuilder assemblyBuilder; Dictionary interfaceToClassMap; private EmitterCache() { AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = Guid.NewGuid().ToString(); assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); DynamicModule = assemblyBuilder.DefineDynamicModule(Guid.NewGuid().ToString()); interfaceToClassMap = new Dictionary(); } private Type[] GetParameterTypes(MethodInfo mInfo) { ParameterInfo[] parameters = mInfo.GetParameters(); Type[] typeArray = new Type[parameters.Length]; int index = 0; for (; index < parameters.Length; index++) { typeArray[index] = parameters[index].ParameterType; } return typeArray; } [SuppressMessage(FxCop.Category.Usage, "CA2301:EmbeddableTypesInContainersRule", MessageId = "interfaceToClassMap", Justification = "No need to support type equivalence here.")] internal Type FindOrCreateType(Type interfaceType) { if (!interfaceType.IsInterface) { throw Fx.AssertAndThrow("Passed in type should be an Interface"); } Type classType = null; lock (this) { interfaceToClassMap.TryGetValue(interfaceType, out classType); if (classType == null) { TypeBuilder typeBuilder = DynamicModule.DefineType(interfaceType.Name + "MarshalByRefObject", TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Abstract, typeof(MarshalByRefObject), new Type[] { interfaceType }); Type[] ctorParams = new Type[] { typeof(ClassInterfaceType) }; ConstructorInfo classCtorInfo = typeof(ClassInterfaceAttribute).GetConstructor(ctorParams); CustomAttributeBuilder attributeBuilder = new CustomAttributeBuilder(classCtorInfo, new object[] { ClassInterfaceType.None }); typeBuilder.SetCustomAttribute(attributeBuilder); typeBuilder.AddInterfaceImplementation(interfaceType); foreach (MethodInfo mInfo in interfaceType.GetMethods()) { MethodBuilder methodInClass = null; methodInClass = typeBuilder.DefineMethod(mInfo.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Abstract | MethodAttributes.Abstract | MethodAttributes.HideBySig | MethodAttributes.NewSlot, mInfo.ReturnType, GetParameterTypes(mInfo)); } classType = typeBuilder.CreateType(); interfaceToClassMap[interfaceType] = classType; } } if (classType == null) { throw Fx.AssertAndThrow("Class Type should not be null at this point"); } return classType; } } }