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; }
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; }
/// <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; }
/// <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); }
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; } }
protected Type GetFromCache(CacheKey key) { return scope.GetFromCache(key); }
protected void AddToCache(CacheKey key, Type type) { scope.RegisterInCache(key, type); }
public Type GetGeneratedType() { var cacheKey = new CacheKey(targetType, targetType, additionalInterfacesToProxy, ProxyGenerationOptions); return(ObtainProxyType(cacheKey, GenerateType)); }