You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@ -0,0 +1,106 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user