/// <summary> /// Determines whether this assembly has internals visible to dynamic proxy. /// </summary> /// <param name="asm">The assembly to inspect.</param> public static bool IsInternalToDynamicProxy(Assembly asm) { using (UpgradableLock locker = new UpgradableLock(internalsToDynProxyLock)) { if (internalsToDynProxy.ContainsKey(asm)) { return internalsToDynProxy[asm]; } locker.Upgrade(); if (internalsToDynProxy.ContainsKey(asm)) { return internalsToDynProxy[asm]; } InternalsVisibleToAttribute[] atts = (InternalsVisibleToAttribute[]) asm.GetCustomAttributes(typeof (InternalsVisibleToAttribute), false); bool found = false; foreach (InternalsVisibleToAttribute internals in atts) { if (internals.AssemblyName.Contains(ModuleScope.DEFAULT_ASSEMBLY_NAME)) { found = true; break; } } internalsToDynProxy.Add(asm, found); return found; } }
public Type GenerateCode(Type proxyTargetType, Type[] interfaces, ProxyGenerationOptions options) { // make sure ProxyGenerationOptions is initialized options.Initialize(); CheckNotGenericTypeDefinition(proxyTargetType, "proxyTargetType"); CheckNotGenericTypeDefinitions(interfaces, "interfaces"); Type generatedType; CacheKey cacheKey = new CacheKey(proxyTargetType, targetType, interfaces, options); using (UpgradableLock locker = new UpgradableLock(Scope.RWLock)) { Type cacheType = GetFromCache(cacheKey); if (cacheType != null) { return cacheType; } locker.Upgrade(); cacheType = GetFromCache(cacheKey); if (cacheType != null) { return cacheType; } SetGenerationOptions(options); String newName = targetType.Name + "Proxy" + Guid.NewGuid().ToString("N"); // Add Interfaces that the proxy implements List<Type> interfaceList = new List<Type>(); interfaceList.Add(targetType); if (interfaces != null) { interfaceList.AddRange(interfaces); } #if SILVERLIGHT #warning What to do? #else if (!interfaceList.Contains(typeof(ISerializable))) interfaceList.Add(typeof(ISerializable)); #endif AddMixinInterfaces(interfaceList); AddDefaultInterfaces(interfaceList); Type baseType = options.BaseTypeForInterfaceProxy; ClassEmitter emitter = BuildClassEmitter(newName, baseType, interfaceList); CreateOptionsField(emitter); emitter.AddCustomAttributes(options); #if SILVERLIGHT #warning XmlIncludeAttribute is in silverlight, do we want to explore this? #else emitter.DefineCustomAttribute(new XmlIncludeAttribute(targetType)); emitter.DefineCustomAttribute(new SerializableAttribute()); #endif // Custom attributes ReplicateNonInheritableAttributes(targetType, emitter); // Fields generations FieldReference interceptorsField = emitter.CreateField("__interceptors", typeof(IInterceptor[])); targetField = emitter.CreateField("__target", proxyTargetType); #if SILVERLIGHT #warning XmlIncludeAttribute is in silverlight, do we want to explore this? #else emitter.DefineCustomAttributeFor(interceptorsField, new XmlIgnoreAttribute()); emitter.DefineCustomAttributeFor(targetField, new XmlIgnoreAttribute()); #endif // Implement builtin Interfaces ImplementProxyTargetAccessor(targetType, emitter, interceptorsField); // Collect methods PropertyToGenerate[] propsToGenerate; EventToGenerate[] eventToGenerates; MethodInfo[] methods = CollectMethodsAndProperties(emitter, targetType, out propsToGenerate, out eventToGenerates); if (interfaces != null && interfaces.Length != 0) { List<Type> tmpInterfaces = new List<Type>(interfaces); foreach (Type inter in interfaces) { if (inter.IsAssignableFrom(proxyTargetType)) { PropertyToGenerate[] tempPropsToGenerate; EventToGenerate[] tempEventToGenerates; MethodInfo[] methodsTemp = CollectMethodsAndProperties(emitter, inter, out tempPropsToGenerate, out tempEventToGenerates); PropertyToGenerate[] newPropsToGenerate = new PropertyToGenerate[tempPropsToGenerate.Length + propsToGenerate.Length]; MethodInfo[] newMethods = new MethodInfo[methodsTemp.Length + methods.Length]; EventToGenerate[] newEvents = new EventToGenerate[eventToGenerates.Length + tempEventToGenerates.Length]; Array.Copy(methods, newMethods, methods.Length); Array.Copy(methodsTemp, 0, newMethods, methods.Length, methodsTemp.Length); Array.Copy(propsToGenerate, newPropsToGenerate, propsToGenerate.Length); Array.Copy(tempPropsToGenerate, 0, newPropsToGenerate, propsToGenerate.Length, tempPropsToGenerate.Length); Array.Copy(eventToGenerates, newEvents, eventToGenerates.Length); Array.Copy(tempEventToGenerates, 0, newEvents, eventToGenerates.Length, tempEventToGenerates.Length); methods = newMethods; propsToGenerate = newPropsToGenerate; eventToGenerates = newEvents; tmpInterfaces.Remove(inter); } } interfaces = tmpInterfaces.ToArray(); } RegisterMixinMethodsAndProperties(emitter, ref methods, ref propsToGenerate, ref eventToGenerates); options.Hook.MethodsInspected(); // Constructor ConstructorEmitter typeInitializer = GenerateStaticConstructor(emitter); if (!proxyTargetType.IsInterface) { CacheMethodTokens(emitter, MethodFinder.GetAllInstanceMethods(proxyTargetType, BindingFlags.Public | BindingFlags.Instance), typeInitializer); } CreateInitializeCacheMethodBody(proxyTargetType, methods, emitter, typeInitializer); FieldReference[] mixinFields = AddMixinFields(emitter); List<FieldReference> fields = new List<FieldReference>(mixinFields); fields.Add(interceptorsField); fields.Add(targetField); GenerateConstructors(emitter, baseType, fields.ToArray()); // GenerateParameterlessConstructor(emitter, interceptorsField, baseType); // Implement interfaces if (interfaces != null && interfaces.Length != 0) { foreach (Type inter in interfaces) { ImplementBlankInterface(targetType, inter, emitter, interceptorsField, typeInitializer, AllowChangeTarget); } } // Create invocation types foreach (MethodInfo method in methods) { CreateInvocationForMethod(emitter, method, proxyTargetType); } // Create methods overrides Dictionary<MethodInfo, MethodEmitter> method2Emitter = new Dictionary<MethodInfo, MethodEmitter>(); foreach (MethodInfo method in methods) { if (method.IsSpecialName && (method.Name.StartsWith("get_") || method.Name.StartsWith("set_") || method.Name.StartsWith("add_") || method.Name.StartsWith("remove_")) || methodsToSkip.Contains(method)) { continue; } NestedClassEmitter nestedClass = (NestedClassEmitter)method2Invocation[method]; MethodEmitter newProxiedMethod = CreateProxiedMethod( targetType, method, emitter, nestedClass, interceptorsField, GetTargetRef(method, mixinFields, targetField), ConstructorVersion.WithTargetMethod, (MethodInfo)method2methodOnTarget[method]); ReplicateNonInheritableAttributes(method, newProxiedMethod); method2Emitter[method] = newProxiedMethod; } foreach (PropertyToGenerate propToGen in propsToGenerate) { if (propToGen.CanRead) { NestedClassEmitter nestedClass = (NestedClassEmitter)method2Invocation[propToGen.GetMethod]; MethodAttributes atts = ObtainMethodAttributes(propToGen.GetMethod); MethodEmitter getEmitter = propToGen.Emitter.CreateGetMethod(atts); ImplementProxiedMethod(targetType, getEmitter, propToGen.GetMethod, emitter, nestedClass, interceptorsField, GetTargetRef(propToGen.GetMethod, mixinFields, targetField), ConstructorVersion.WithTargetMethod, (MethodInfo)method2methodOnTarget[propToGen.GetMethod]); ReplicateNonInheritableAttributes(propToGen.GetMethod, getEmitter); // emitter.TypeBuilder.DefineMethodOverride(getEmitter.MethodBuilder, propToGen.GetMethod); } if (propToGen.CanWrite) { NestedClassEmitter nestedClass = (NestedClassEmitter)method2Invocation[propToGen.SetMethod]; MethodAttributes atts = ObtainMethodAttributes(propToGen.SetMethod); MethodEmitter setEmitter = propToGen.Emitter.CreateSetMethod(atts); ImplementProxiedMethod(targetType, setEmitter, propToGen.SetMethod, emitter, nestedClass, interceptorsField, GetTargetRef(propToGen.SetMethod, mixinFields, targetField), ConstructorVersion.WithTargetMethod, (MethodInfo)method2methodOnTarget[propToGen.SetMethod]); ReplicateNonInheritableAttributes(propToGen.SetMethod, setEmitter); // emitter.TypeBuilder.DefineMethodOverride(setEmitter.MethodBuilder, propToGen.SetMethod); } } foreach (EventToGenerate eventToGenerate in eventToGenerates) { NestedClassEmitter add_nestedClass = (NestedClassEmitter)method2Invocation[eventToGenerate.AddMethod]; MethodAttributes add_atts = ObtainMethodAttributes(eventToGenerate.AddMethod); MethodEmitter addEmitter = eventToGenerate.Emitter.CreateAddMethod(add_atts); ImplementProxiedMethod(targetType, addEmitter, eventToGenerate.AddMethod, emitter, add_nestedClass, interceptorsField, GetTargetRef(eventToGenerate.AddMethod, mixinFields, targetField), ConstructorVersion.WithTargetMethod, (MethodInfo)method2methodOnTarget[eventToGenerate.AddMethod]); ReplicateNonInheritableAttributes(eventToGenerate.AddMethod, addEmitter); NestedClassEmitter remove_nestedClass = (NestedClassEmitter)method2Invocation[eventToGenerate.RemoveMethod]; MethodAttributes remove_atts = ObtainMethodAttributes(eventToGenerate.RemoveMethod); MethodEmitter removeEmitter = eventToGenerate.Emitter.CreateRemoveMethod(remove_atts); ImplementProxiedMethod(targetType, removeEmitter, eventToGenerate.RemoveMethod, emitter, remove_nestedClass, interceptorsField, GetTargetRef(eventToGenerate.RemoveMethod, mixinFields, targetField), ConstructorVersion.WithTargetMethod, (MethodInfo)method2methodOnTarget[eventToGenerate.RemoveMethod]); ReplicateNonInheritableAttributes(eventToGenerate.RemoveMethod, removeEmitter); } #if SILVERLIGHT #warning What to do? #else ImplementGetObjectData(emitter, interceptorsField, mixinFields, interfaces); #endif // Complete Initialize CompleteInitCacheMethod(typeInitializer.CodeBuilder); // Crosses fingers and build type generatedType = emitter.BuildType(); InitializeStaticFields(generatedType); /*foreach (MethodInfo m in TypeFinder.GetMethods(generatedType, BindingFlags.Instance | BindingFlags.Public)) { ParameterInfo[] parameters = m.GetParameters(); // Console.WriteLine(m.Name); for (int i = 0; i < parameters.Length; i++) { ParameterInfo paramInfo = parameters[i]; // Console.WriteLine("{0} {1} {2} {3}", paramInfo.Name, paramInfo.ParameterType, paramInfo.Attributes, paramInfo.Position); // Console.WriteLine("{0} {1} {2} {3}", paramInfo2.Name, paramInfo2.ParameterType, paramInfo2.Attributes, paramInfo2.Position); } } */ AddToCache(cacheKey, generatedType); } return generatedType; }
public Type GenerateCode(Type[] interfaces, ProxyGenerationOptions options) { // make sure ProxyGenerationOptions is initialized options.Initialize(); CheckNotGenericTypeDefinitions(interfaces, "interfaces"); Type type; CacheKey cacheKey = new CacheKey(targetType, interfaces, options); using (UpgradableLock locker = new UpgradableLock(Scope.RWLock)) { Type cacheType = GetFromCache(cacheKey); if (cacheType != null) { return cacheType; } locker.Upgrade(); cacheType = GetFromCache(cacheKey); if (cacheType != null) { return cacheType; } SetGenerationOptions(options); String newName = targetType.Name + "Proxy" + Guid.NewGuid().ToString("N"); // Add Interfaces that the proxy implements List<Type> interfaceList = new List<Type>(); if (interfaces != null) { interfaceList.AddRange(interfaces); } AddMixinInterfaces(interfaceList); AddDefaultInterfaces(interfaceList); #if !SILVERLIGHT if (targetType.IsSerializable) { delegateToBaseGetObjectData = VerifyIfBaseImplementsGetObjectData(targetType); if (!interfaceList.Contains(typeof(ISerializable))) { interfaceList.Add(typeof(ISerializable)); } } #endif ClassEmitter emitter = BuildClassEmitter(newName, targetType, interfaceList); CreateOptionsField(emitter); emitter.AddCustomAttributes(options); #if !SILVERLIGHT emitter.DefineCustomAttribute(new XmlIncludeAttribute(targetType)); #endif // Custom attributes ReplicateNonInheritableAttributes(targetType, emitter); // Fields generations FieldReference interceptorsField = emitter.CreateField("__interceptors", typeof (IInterceptor[])); // Implement builtin Interfaces ImplementProxyTargetAccessor(targetType, emitter, interceptorsField); #if !SILVERLIGHT emitter.DefineCustomAttributeFor(interceptorsField, new XmlIgnoreAttribute()); #endif // Collect methods PropertyToGenerate[] propsToGenerate; EventToGenerate[] eventToGenerates; MethodInfo[] methods = CollectMethodsAndProperties(emitter, targetType, out propsToGenerate, out eventToGenerates); RegisterMixinMethodsAndProperties(emitter, ref methods, ref propsToGenerate, ref eventToGenerates); options.Hook.MethodsInspected(); // Constructor ConstructorEmitter typeInitializer = GenerateStaticConstructor(emitter); FieldReference[] mixinFields = AddMixinFields(emitter); // constructor arguments List<FieldReference> constructorArguments = new List<FieldReference>(mixinFields); constructorArguments.Add(interceptorsField); CreateInitializeCacheMethodBody(targetType, methods, emitter, typeInitializer); GenerateConstructors(emitter, targetType, constructorArguments.ToArray()); GenerateParameterlessConstructor(emitter, targetType, interceptorsField); #if !SILVERLIGHT if (delegateToBaseGetObjectData) { GenerateSerializationConstructor(emitter, interceptorsField, mixinFields); } #endif // Implement interfaces if (interfaces != null && interfaces.Length != 0) { foreach (Type inter in interfaces) { ImplementBlankInterface(targetType, inter, emitter, interceptorsField, typeInitializer); } } // Create callback methods Dictionary<MethodInfo, MethodBuilder> method2Callback = new Dictionary<MethodInfo, MethodBuilder>(); foreach (MethodInfo method in methods) { method2Callback[method] = CreateCallbackMethod(emitter, method, method); } // Create invocation types Dictionary<MethodInfo, NestedClassEmitter> method2Invocation = new Dictionary<MethodInfo, NestedClassEmitter>(); foreach (MethodInfo method in methods) { MethodBuilder callbackMethod = method2Callback[method]; method2Invocation[method] = BuildInvocationNestedType(emitter, targetType, IsMixinMethod(method) ? method.DeclaringType : emitter.TypeBuilder, method, callbackMethod, ConstructorVersion.WithoutTargetMethod); } // Create methods overrides Dictionary<MethodInfo, MethodEmitter> method2Emitter = new Dictionary<MethodInfo, MethodEmitter>(); foreach (MethodInfo method in methods) { if (method.IsSpecialName && (method.Name.StartsWith("get_") || method.Name.StartsWith("set_") || method.Name.StartsWith("add_") || method.Name.StartsWith("remove_")) || methodsToSkip.Contains(method)) { continue; } NestedClassEmitter nestedClass = method2Invocation[method]; Reference targetRef = GetTargetRef(method, mixinFields, SelfReference.Self); MethodEmitter newProxiedMethod = CreateProxiedMethod( targetType, method, emitter, nestedClass, interceptorsField, targetRef, ConstructorVersion.WithoutTargetMethod, null); ReplicateNonInheritableAttributes(method, newProxiedMethod); method2Emitter[method] = newProxiedMethod; } foreach (PropertyToGenerate propToGen in propsToGenerate) { if (propToGen.CanRead) { NestedClassEmitter nestedClass = method2Invocation[propToGen.GetMethod]; MethodAttributes atts = ObtainMethodAttributes(propToGen.GetMethod); MethodEmitter getEmitter = propToGen.Emitter.CreateGetMethod(atts); Reference targetRef = GetTargetRef(propToGen.GetMethod, mixinFields, SelfReference.Self); ImplementProxiedMethod(targetType, getEmitter, propToGen.GetMethod, emitter, nestedClass, interceptorsField, targetRef, ConstructorVersion.WithoutTargetMethod, null); ReplicateNonInheritableAttributes(propToGen.GetMethod, getEmitter); } if (propToGen.CanWrite) { NestedClassEmitter nestedClass = method2Invocation[propToGen.SetMethod]; MethodAttributes atts = ObtainMethodAttributes(propToGen.SetMethod); MethodEmitter setEmitter = propToGen.Emitter.CreateSetMethod(atts); Reference targetRef = GetTargetRef(propToGen.SetMethod, mixinFields, SelfReference.Self); ImplementProxiedMethod(targetType, setEmitter, propToGen.SetMethod, emitter, nestedClass, interceptorsField, targetRef, ConstructorVersion.WithoutTargetMethod, null); ReplicateNonInheritableAttributes(propToGen.SetMethod, setEmitter); } } foreach (EventToGenerate eventToGenerate in eventToGenerates) { NestedClassEmitter add_nestedClass = method2Invocation[eventToGenerate.AddMethod]; MethodAttributes add_atts = ObtainMethodAttributes(eventToGenerate.AddMethod); MethodEmitter addEmitter = eventToGenerate.Emitter.CreateAddMethod(add_atts); ImplementProxiedMethod(targetType, addEmitter, eventToGenerate.AddMethod, emitter, add_nestedClass, interceptorsField, GetTargetRef(eventToGenerate.AddMethod, mixinFields, SelfReference.Self), ConstructorVersion.WithoutTargetMethod, null); ReplicateNonInheritableAttributes(eventToGenerate.AddMethod, addEmitter); NestedClassEmitter remove_nestedClass = method2Invocation[eventToGenerate.RemoveMethod]; MethodAttributes remove_atts = ObtainMethodAttributes(eventToGenerate.RemoveMethod); MethodEmitter removeEmitter = eventToGenerate.Emitter.CreateRemoveMethod(remove_atts); ImplementProxiedMethod(targetType, removeEmitter, eventToGenerate.RemoveMethod, emitter, remove_nestedClass, interceptorsField, GetTargetRef(eventToGenerate.RemoveMethod, mixinFields, SelfReference.Self), ConstructorVersion.WithoutTargetMethod, null); ReplicateNonInheritableAttributes(eventToGenerate.RemoveMethod, removeEmitter); } #if !SILVERLIGHT ImplementGetObjectData(emitter, interceptorsField, mixinFields, interfaces); #endif // Complete type initializer code body CompleteInitCacheMethod(typeInitializer.CodeBuilder); // Build type type = emitter.BuildType(); InitializeStaticFields(type); AddToCache(cacheKey, type); } return type; }