DefaultProxyBuilder
using Castle.Core.Internal;
using Castle.Core.Logging;
using Castle.DynamicProxy.Generators;
using Castle.DynamicProxy.Internal;
using System;
using System.Collections.Generic;
using System.Reflection;
namespace Castle.DynamicProxy
{
public class DefaultProxyBuilder : IProxyBuilder
{
private readonly ModuleScope scope;
private ILogger logger = NullLogger.Instance;
public ILogger Logger {
get {
return logger;
}
set {
logger = value;
}
}
public ModuleScope ModuleScope => scope;
public DefaultProxyBuilder()
: this(new ModuleScope())
{
}
public DefaultProxyBuilder(ModuleScope scope)
{
this.scope = scope;
}
public Type CreateClassProxyType(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
{
AssertValidType(classToProxy);
AssertValidTypes(additionalInterfacesToProxy);
return new ClassProxyGenerator(scope, classToProxy) {
Logger = logger
}.GenerateCode(additionalInterfacesToProxy, options);
}
public Type CreateClassProxyTypeWithTarget(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
{
AssertValidType(classToProxy);
AssertValidTypes(additionalInterfacesToProxy);
return new ClassProxyWithTargetGenerator(scope, classToProxy, additionalInterfacesToProxy, options) {
Logger = logger
}.GetGeneratedType();
}
public Type CreateInterfaceProxyTypeWithTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, Type targetType, ProxyGenerationOptions options)
{
AssertValidType(interfaceToProxy);
AssertValidTypes(additionalInterfacesToProxy);
return new InterfaceProxyWithTargetGenerator(scope, interfaceToProxy) {
Logger = logger
}.GenerateCode(targetType, additionalInterfacesToProxy, options);
}
public Type CreateInterfaceProxyTypeWithTargetInterface(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
{
AssertValidType(interfaceToProxy);
AssertValidTypes(additionalInterfacesToProxy);
return new InterfaceProxyWithTargetInterfaceGenerator(scope, interfaceToProxy) {
Logger = logger
}.GenerateCode(interfaceToProxy, additionalInterfacesToProxy, options);
}
public Type CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
{
AssertValidType(interfaceToProxy);
AssertValidTypes(additionalInterfacesToProxy);
return new InterfaceProxyWithoutTargetGenerator(scope, interfaceToProxy) {
Logger = logger
}.GenerateCode(typeof(object), additionalInterfacesToProxy, options);
}
private void AssertValidType(Type target)
{
AssertValidTypeForTarget(target, target);
}
private void AssertValidTypeForTarget(Type type, Type target)
{
if (type.GetTypeInfo().get_IsGenericTypeDefinition())
throw new GeneratorException($"""{target.GetBestName()}""{type.GetBestName()}""");
if (!IsPublic(type) && !IsAccessible(type))
throw new GeneratorException(ExceptionMessageBuilder.CreateMessageForInaccessibleType(type, target));
Type[] genericArguments = System.Reflection.TypeExtensions.GetGenericArguments(type);
foreach (Type type2 in genericArguments) {
AssertValidTypeForTarget(type2, target);
}
}
private void AssertValidTypes(IEnumerable<Type> targetTypes)
{
if (targetTypes != null) {
foreach (Type targetType in targetTypes) {
AssertValidType(targetType);
}
}
}
private bool IsAccessible(Type target)
{
if (IsInternal(target))
return target.GetTypeInfo().get_Assembly().IsInternalToDynamicProxy();
return false;
}
private bool IsPublic(Type target)
{
if (!target.GetTypeInfo().get_IsPublic())
return target.GetTypeInfo().get_IsNestedPublic();
return true;
}
private static bool IsInternal(Type target)
{
bool isNested = target.IsNested;
bool flag = isNested && (target.GetTypeInfo().get_IsNestedAssembly() || target.GetTypeInfo().get_IsNestedFamORAssem());
return (!target.GetTypeInfo().get_IsVisible() && !isNested) | flag;
}
}
}