private Type GetInvocationType(MetaMethod method, ClassEmitter emitter, ProxyGenerationOptions options)
		{
			var scope = emitter.ModuleScope;
			Type[] invocationInterfaces;
			if (canChangeTarget)
			{
				invocationInterfaces = new[] { typeof(IInvocation), typeof(IChangeProxyTarget) };
			}
			else
			{
				invocationInterfaces = new[] { typeof(IInvocation) };
			}
			var key = new CacheKey(method.Method, CompositionInvocationTypeGenerator.BaseType, invocationInterfaces, null);

			// no locking required as we're already within a lock

			var invocation = scope.GetFromCache(key);
			if (invocation != null)
			{
				return invocation;
			}

			invocation = new CompositionInvocationTypeGenerator(method.Method.DeclaringType,
																method,
																method.Method,
																canChangeTarget,
																null)
				.Generate(emitter, options, namingScope)
				.BuildType();

			scope.RegisterInCache(key, invocation);

			return invocation;
		}
Ejemplo n.º 2
0
		public Type GenerateCode(Type[] interfaces, ProxyGenerationOptions options)
		{
			// make sure ProxyGenerationOptions is initialized
			options.Initialize();

			interfaces = TypeUtil.GetAllInterfaces(interfaces);
			CheckNotGenericTypeDefinitions(interfaces, "interfaces");
			ProxyGenerationOptions = options;
			var cacheKey = new CacheKey(targetType, interfaces, options);
			return ObtainProxyType(cacheKey, (n, s) => GenerateType(n, interfaces, s));
		}
		private Type GetInvocationType(MetaMethod method, ClassEmitter emitter, ProxyGenerationOptions options)
		{
			var scope = emitter.ModuleScope;
			var key = new CacheKey(method.Method, CompositionInvocationTypeGenerator.BaseType, null, null);

			// no locking required as we're already within a lock
			var invocation = scope.GetFromCache(key);
			if (invocation != null)
			{
				return invocation;
			}

			invocation = new CompositionInvocationTypeGenerator(method.Method.DeclaringType,
			                                                    method,
			                                                    method.Method,
			                                                    false,
			                                                    null)
				.Generate(emitter, options, namingScope)
				.BuildType();

			scope.RegisterInCache(key, invocation);

			return invocation;
		}
Ejemplo n.º 4
0
		/// <summary>
		///   Registers a type in this scope's type cache.
		/// </summary>
		/// <param name = "key">The key to be associated with the type.</param>
		/// <param name = "type">The type to be stored in the cache.</param>
		public void RegisterInCache(CacheKey key, Type type)
		{
			typeCache[key] = type;
		}
Ejemplo n.º 5
0
		/// <summary>
		///   Returns a type from this scope's type cache, or null if the key cannot be found.
		/// </summary>
		/// <param name = "key">The key to be looked up in the cache.</param>
		/// <returns>The type from this scope's type cache matching the key, or null if the key cannot be found</returns>
		public Type GetFromCache(CacheKey key)
		{
			Type type;
			typeCache.TryGetValue(key, out type);
			return type;
		}
		public Type GetGeneratedType()
		{
			var cacheKey = new CacheKey(targetType, targetType, additionalInterfacesToProxy, ProxyGenerationOptions);
			return ObtainProxyType(cacheKey, GenerateType);
		}
		private Type GetInvocationType(MetaMethod method, ClassEmitter @class, ProxyGenerationOptions options)
		{
			var scope = @class.ModuleScope;
			var invocationInterfaces = new[] { typeof(IInvocation) };

			var key = new CacheKey(method.Method, CompositionInvocationTypeGenerator.BaseType, invocationInterfaces, null);

			// no locking required as we're already within a lock

			var invocation = scope.GetFromCache(key);
			if (invocation != null)
			{
				return invocation;
			}
			invocation = BuildInvocationType(method, @class, options);

			scope.RegisterInCache(key, invocation);

			return invocation;
		}
		private Type GetDelegateType(MetaMethod method, ClassEmitter @class, ProxyGenerationOptions options)
		{
			var scope = @class.ModuleScope;
			var key = new CacheKey(
				typeof(Delegate),
				targetType,
				new[] { method.MethodOnTarget.ReturnType }
					.Concat(ArgumentsUtil.GetTypes(method.MethodOnTarget.GetParameters())).
					ToArray(),
				null);

			var type = scope.GetFromCache(key);
			if (type != null)
			{
				return type;
			}

			type = new DelegateTypeGenerator(method, targetType)
				.Generate(@class, options, namingScope)
				.BuildType();

			scope.RegisterInCache(key, type);

			return type;
		}
		public Type GetProxyType()
		{
			var cacheKey = new CacheKey(targetType, null, null);
			return ObtainProxyType(cacheKey, GenerateType);
		}
Ejemplo n.º 10
0
		protected Type ObtainProxyType(CacheKey cacheKey, Func<string, INamingScope, Type> factory)
		{
			using (var locker = Scope.Lock.ForReadingUpgradeable())
			{
				var cacheType = GetFromCache(cacheKey);
				if (cacheType != null)
				{
					Logger.DebugFormat("Found cached proxy type {0} for target type {1}.", cacheType.FullName, targetType.FullName);
					return cacheType;
				}

				// Upgrade the lock to a write lock, then read again. This is to avoid generating duplicate types
				// under heavy multithreaded load.
				locker.Upgrade();

				cacheType = GetFromCache(cacheKey);
				if (cacheType != null)
				{
					Logger.DebugFormat("Found cached proxy type {0} for target type {1}.", cacheType.FullName, targetType.FullName);
					return cacheType;
				}

				// Log details about the cache miss
				Logger.DebugFormat("No cached proxy type was found for target type {0}.", targetType.FullName);
				EnsureOptionsOverrideEqualsAndGetHashCode(ProxyGenerationOptions);

				var name = Scope.NamingScope.GetUniqueName("Castle.Proxies." + targetType.Name + "Proxy");
				var proxyType = factory.Invoke(name, Scope.NamingScope.SafeSubScope());

				AddToCache(cacheKey, proxyType);
				return proxyType;
			}
		}
Ejemplo n.º 11
0
		protected Type GetFromCache(CacheKey key)
		{
			return scope.GetFromCache(key);
		}
Ejemplo n.º 12
0
		protected void AddToCache(CacheKey key, Type type)
		{
			scope.RegisterInCache(key, type);
		}
Ejemplo n.º 13
0
        public Type GetGeneratedType()
        {
            var cacheKey = new CacheKey(targetType, targetType, additionalInterfacesToProxy, ProxyGenerationOptions);

            return(ObtainProxyType(cacheKey, GenerateType));
        }