How do virtual proxies work?

I'm having trouble moving my head around virtual proxies. I read many articles and spent several hours trying to find good information, but I still have to find something comprehensive. Therefore, I will make a general request here to get more accurate information (either posted here, or just a link). I will also add some details below to better explain what exactly I want.

I have several objects and there are many links between them. For brevity, I will have one object (Node) with basic parent-child relationships. When I pull this object out of the database, I would like to implement lazy loading. From what I read, the virtual proxy will essentially handle all the lazy loading for me, referring to the interface (INode) and pulling the data items as needed. [Note. I don’t actually have an INode class, but when I put the virtual keyword in my data, maybe a proxy was used]

When I make data members in my classes virtual, it seems to make proxies. Is this a virtual proxy? Do they do lazy loading?

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

This is my current Node.cs

[DataContract(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 moment I am very confused and I just need to be guided by this topic or even an online resource that I can look at, since everything I found was less useful.

Thanks in advance.

+4
source share
2 answers

A "virtual" proxy and lazy loading is something related to ORM tools. The proxy server is actually not virtual, it is dynamic, and it matches the real proxy pattern defined by GoF.

A dynamic proxy is a class created by the ORM tool at runtime (it is not defined as a code file anywhere). It comes from your object, and it overrides the navigation properties. Because of this, they must be virtual in order to make proxies work. The proxy server has the navigation state property in a closed field or in any more complex structure, and if access to the property is first opened, it sees that the state has been unloaded and loading from the database and change of state for loading are started.

In any case, I'm not sure how this relates to WCF, because best practice does not use lazy loading with WCF. Why?

  • If you use lazy loading on the server side, serialization will always be retrieved from the graph of the entire database object, since serialization will access each navigation property and start lazy loading, but then it will serialize lazy loaded objects and access to all their navigation properties, etc. d.
  • Lazy loading from the client side looks like something. First of all, lazy loading on the client side is completely up to you - you must implement it. When using services, you should always follow one of the principles of SOA: the boundary of the service is explicit. This means that the user of your object should always know that he is making a remote call instead of a local call. The main goal of distributed computing is to reduce circular transitions across networks, so you can use energetic loading and transfer all the necessary data in one reverse direction, if possible, instead of using delayed loading. The same applies for loading from a database - use lazy loading when it makes sense, since roundrips to database can be expensive operations.
+5
source

I think you want some private fields to support your virtual properties. In the get overrides parameters of these virtual properties, you check the private field to see if it is really valid at the moment (it is already received from db, it corresponds to the date, etc.) - if not, select or return it. I don’t see it being more 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; } } 
+1
source

All Articles