| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- //-----------------------------------------------------------------------------
- // 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<Type, Type> 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<Type, Type>();
- }
- 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;
- }
- }
- }
|