C# CastleDynamic仅获取虚拟值
当我在测试城堡炸药时,我发现了一种奇怪的行为 我没有找到好的文档,所以我找到的更接近的信息是论文2 和 有了它,我假设,当您使用CreateClassProxyWithTarget时,所有内容都进入类并返回到代理,因此如果Prop/函数不是虚拟的,它只返回类值 我想,有了代码示例,我的问题就清楚了 让我们假设我有这个代码 主要 拦截器C# CastleDynamic仅获取虚拟值,c#,castle-dynamicproxy,dynamic-proxy,C#,Castle Dynamicproxy,Dynamic Proxy,当我在测试城堡炸药时,我发现了一种奇怪的行为 我没有找到好的文档,所以我找到的更接近的信息是论文2 和 有了它,我假设,当您使用CreateClassProxyWithTarget时,所有内容都进入类并返回到代理,因此如果Prop/函数不是虚拟的,它只返回类值 我想,有了代码示例,我的问题就清楚了 让我们假设我有这个代码 主要 拦截器 public static class Interceptor { private static readonly ProxyGenerator _ge
public static class Interceptor
{
private static readonly ProxyGenerator _generator = new ProxyGenerator();
public static TEntity AddProxy<TEntity>(TEntity entity) where TEntity: class, new()
{
var proxy = _generator.CreateClassProxyWithTarget(entity, new LogInterceptor());
return proxy;
}
}
结果是
OBJ非虚拟字符串:非虚拟值| |虚拟字符串虚拟值
拦截:使用值获取虚拟字符串:虚拟值
代理非虚拟字符串:NULL| | VisrtualString虚拟值
预期的结果是
OBJ非虚拟字符串:非虚拟值| |虚拟字符串虚拟值
拦截:使用值获取虚拟字符串:虚拟值
代理非虚拟字符串:非虚拟值| |虚拟字符串虚拟值
那么,如果结果是对的,我该怎么做,用Castle或其他Lib我正在尝试的东西(仅过度隐藏虚拟对象并保持非虚拟对象的可访问性?您可能无法。无论如何,使用基于组合的
CreateClassProxyWithTarget
都不行。当您在这样的代理对象上调用非虚拟方法时,您完全绕过了DynamicProxy;它无法拦截该调用,因此不会阻止您的请求。)将其rd到目标对象。因此,您可以返回代理对象自身未初始化的非虚拟字符串属性的值
您可以使用基于继承的代理,即使用CreateClassProxy
。使用这种方法,您将只有一个对象(代理)因此,您可以直接在代理对象上而不是在单独的目标上设置属性值,而不是两个。然后,即使DynamicProxy仍然无法截获对非虚拟字符串的getter的调用,调用将只使用原始类的getter。因为属性不是虚拟的,代理类也无法覆盖当您调用Interceptor.AddProxy()时
它创建了一个从SomeClass
继承的类型的新对象。此对象将有自己的VirtualString
值,并且NonVirtualString
将被库覆盖以使用拦截器,但NonVirtualString
将不会被覆盖,并保持为空,因为这是字符串的默认值
您可以尝试改用接口拦截。否则,您将无法拦截非虚拟方法/属性
public static class Interceptor
{
private static readonly ProxyGenerator _generator = new ProxyGenerator();
public static TEntity AddProxy<TEntity>(TEntity entity) where TEntity: class, new()
{
var proxy = _generator.CreateClassProxyWithTarget(entity, new LogInterceptor());
return proxy;
}
}
[Serializable]
public class LogInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
try
{
invocation.Proceed();
Console.WriteLine("Intercepting: {0} with value: {1}", invocation.Method.Name, invocation.ReturnValue);
}
catch (Exception ex)
{
Console.WriteLine(string.Format("Exception in method {0}{1}{2}", invocation.Method.Name,
Environment.NewLine, ex.Message));
throw;
}
}
}