开发者

How do virtual proxies work?

I am having some trouble wrapping my head around virtual proxies. I have read tons of articles and spent several hours trying to find good information, but I have yet to find something comprehensive. So I will make a generic request here for better information (either posted here or just a link). I will also add some detail below to better explain what exactly it is I want.

I have several objects and there are many references between them. For the sake of brevity I will have one object (Node) with a basic parent-child relationship. When I pull this object out of the database, I would like to implement lazy-loading. From what I have read, a virtual proxy will essentially handle all the lazy-loading for me by referencing the interface (INode) and pulling data members as needed. [Note: I do not actually have an INode class, but when I put the virtual keyword on my data members, a proxy did seem to be used]

When I make data members in my classes virtual, it seems to make a proxy. Is this a virtual proxy? Do these implement lazy-loading?

I searched for information about the virtual keyword, but the only documentation I could find was to use it on methods, which is used for inheritance so that derived classes can override the function, which has nothing to do with what I want (I think).

This is my current Node.cs

[D开发者_Go百科ataContract(IsReference=true)]
public partial class Node
{
  [DataMember]
  public long ID { get; private set; }
  [DataMember]
  public virtual Node Parent { get; set; }
  [DataMember]
  public virtual ICollection<Node> Children { get; set; }
}

Basically at this point I am very confused and just need some guidance on this topic, or even an online resource that I can look to, since all the ones I have found have been less than helpful.

Thanks in advance.


"Virtual" proxy and lazy loading is something related to ORM tools. The proxy actually is not virtual it is dynamic and it follows real Proxy pattern defined by GoF.

Dynamic proxy is class created by ORM tool at runtime (it is not defined as a code file anywhere). It derives from your entity and it overrides navigation properties. Because of that they must be virtual to make a proxy work. The proxy holds a state of navigation property in private field or any more complex structure and if the property is accessed first time it sees that the state is unloaded and triggers loading from database and change the state to loaded.

Anyway I'm not sure how this refers to WCF because best practice is not using lazy loading with WCF. Why?

  • If you use lazy loading on server side serialization will always pull from database whole object graph because serialization will access every navigation property and triggers lazy loading but it will then start serializing lazy loaded entities and access all their navigation properties, etc.
  • Lazy loading on client side is something blured. First of all lazy loading on client side is completely up to you - you must implement it. When using services you should always follow one of SOA tenets: Service boundary is explicit. It means that user of your object should always know that he is doing remote call instead of local call. Main target in distributed computing is reducing network roundtrips so you should use eager loading and transfer all needed data in a single roundtrip if possible instead of using deferred loading. The same is applicable for loading from database - use lazy loading when it make sense because roundrips to database can be costly operations.


I think you want some private fields backing your virtual properites. In the get overrides of these virtual properties you check the private field to see if its currently valid (has it been got already from db, is it upto date etc) - if not then fetch or refetch it. I don't see it has to been anymore complicated than that.

Base class:

private Node _Parent;
public virtual Node Parent { 
    get { return _Parent; } // Default no lazy fetch.
}

Override:

public override Node Parent {
    get {
        if (_Parent==null) // or out of date, dirty etc
            Do_db_get_of_parent();
        return _Parent;
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜