【问题标题】:Castle DynamicProxy CreateClassProxyWithTarget not using underlying object for non-intercepted propertiesCastle DynamicProxy CreateClassProxyWithTarget 不使用底层对象进行非拦截属性
【发布时间】:2014-03-15 08:11:18
【问题描述】:

我有一些简单的 DTO 类,例如:

[XmlType]
class Person : AbstractResource
{
  [XmlElement("name")]
  public virtual string FirstName { get; set; }

  public virtual string Nickname { get { return "Mister cool"; } }
}

class SpecialPerson : Person
{
  public override string NickName { get { return FirstName; } }
}

在我的代码中,我从 XML 文件中反序列化 Person/SpecialPerson 对象列表,然后尝试使用 CreateClassProxyWithTarget 将它们全部包装在代理实例中。出于某种原因,对于任何 SpecialPerson 代理,FirstName 始终为 null 并且 NickName 为 null,但对于任何 Person 代理返回“Mister cool”。

我进入调试器并查看了底层的包装对象,它具有所有正确的值。我还注意不要拦截名字或昵称。我希望代理简单地调用被包装的对象,并且在某些情况下它会 [1] 但大多数情况下它不会。我做错了什么?

[1] 在我的拦截器代码中,我通过反射设置了被包装对象的一些属性,并且 那些 正确显示。但我不明白为什么这些属性会从底层对象中读取,而其他属性则不会。当调用 Invoke 时,几乎就像任何被截获的属性都会调用被包装的对象,但对于您为 ShouldInterceptMethod 返回 false 的任何方法,它不会。但这对我来说毫无意义,如果我说不拦截包装对象上的方法,应该采取什么其他可能的操作,而只是使用包装对象的属性?

【问题讨论】:

    标签: c# castle-dynamicproxy


    【解决方案1】:

    天哪,我对回答自己的问题感到难过,但我找出了问题所在,我希望这能帮助遇到这种情况的其他人。我在谷歌上找不到任何关于此的内容。

    所以问题是,即使您创建了一个包装现有对象的代理(即使用 CreateClassProxyWithTarget),它仍然创建一个全新的对象。碰巧该对象有一种获取包装对象的方法。对于您不拦截的任何方法、属性等,它们将在代理对象上调用。在属性的情况下,它们不会使用包装对象中的值,即使属性是虚拟的,因为代理对象拥有所有这些属性的自己的副本。

    要解决这个问题,你必须摆脱你的选择钩子,只拦截一切。如果它是您实际上不想拦截的属性,您可以简单地调用invocation.Proceed。这将导致它将请求转发到包装对象。

    【讨论】:

    • 不要因为回答自己的问题而感到难过。 StackOverflow 支持甚至鼓励这样做(当你创建一个新问题时,有一个“回答你自己的问题”选项)。这个网站旨在分享知识,非常感谢您找到答案并将其发布在这里以供其他人查找。
    • 如何处理非虚拟属性?我希望一些属性命中 IInterceptor(虚拟的),其余的实际应用于代理对象。
    • 非常感谢。我永远不会想到这一点。我也完全期望将未拦截的调用传递给 wrapped 对象。他们去 new 对象对我来说毫无意义(我想这只是代理对象本身的基本实现......但在字段中没有任何数据,这无济于事)。从我的角度来看,它的工作方式非常具有误导性。
    猜你喜欢
    • 2023-03-03
    • 2011-04-26
    • 2012-03-31
    • 2018-06-23
    • 2011-02-26
    • 2018-10-06
    • 2012-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多