Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><strong>RealProxy lets you create your own proxies for existing types.</strong></p> <p>This is super-advanced and I haven't seen anyone else use it -- which may mean that it's also really not that useful for most folks -- but it's one of those things that's good to know. </p> <p>Basically, the .NET <strong>RealProxy</strong> class lets you create what is called a <em>transparent proxy</em> to another type. Transparent in this case means that it looks completely like the proxied target object to its client -- but it's really not: it's an instance of your class, which is derived from RealProxy. </p> <p>This lets you apply powerful and comprehensive interception and "intermediation" services between the client and any methods or properties invoked on the real target object. Couple this power with the factory pattern (IoC etc), and you can hand back transparent proxies instead of real objects, allowing you to intercept all calls to the real objects and perform actions before and after each method invocation. In fact, I believe this is the very functionality .NET uses for remoting across app domain, process, and machine boundaries: .NET intercepts all access, sends serialized info to the remote object, receives the response, and returns it to your code.</p> <p>Maybe an example will make it clear how this can be useful: I created a reference service stack for my last job as enterprise architect which specified the standard internal composition (the "stack") of any new WCF services across the division. The model mandated that the data access layer for (say) the Foo service implement <code>IDAL&lt;Foo&gt;:</code> create a Foo, read a Foo, update a Foo, delete a Foo. Service developers used supplied common code (from me) that would locate and load the required DAL for a service: </p> <pre><code>IDAL&lt;T&gt; GetDAL&lt;T&gt;(); // retrieve data access layer for entity T </code></pre> <p>Data access strategies in that company had often been, well, performance-challenged. As an architect, I couldn't watch over every service developer to make sure that he/she wrote a performant data access layer. But what I could do within the <em>GetDAL</em> factory pattern was create <strong>a transparent proxy</strong> to the requested DAL (once the common service model code located the DLL and loaded it), and use high-performance timing APIs to profile all calls to any method of the DAL. Ranking laggards then is just a matter of sorting DAL call timings by descending total time. The advantage to this over development profiling (e.g. in the IDE) is that it can be done in the production environment as well, to ensure SLAs. </p> <p>Here is an example of test code I wrote for the "entity profiler," which was common code to create a profiling proxy for any type with a single line:</p> <pre><code>[Test, Category("ProfileEntity")] public void MyTest() { // this is the object that we want profiled. // we would normally pass this around and call // methods on this instance. DALToBeProfiled dal = new DALToBeProfiled(); // To profile, instead we obtain our proxy // and pass it around instead. DALToBeProfiled dalProxy = (DALToBeProfiled)EntityProfiler.Instance(dal); // or... DALToBeProfiled dalProxy2 = EntityProfiler&lt;DALToBeProfiled&gt;.Instance(dal); // Now use proxy wherever we would have used the original... // All methods' timings are automatically recorded // with a high-resolution timer DoStuffToThisObject(dalProxy); // Output profiling results ProfileManager.Instance.ToConsole(); } </code></pre> <p>Again, this lets you intercept all methods and properties called by the client on the target object! In your <em>RealProxy-derived</em> class, you have to override <strong>Invoke:</strong></p> <pre><code>[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)] // per FxCop public override IMessage Invoke(IMessage msg) { IMethodCallMessage msgMethodCall = msg as IMethodCallMessage; Debug.Assert(msgMethodCall != null); // should not be null - research Invoke if this trips. KWB 2009.05.28 // The MethodCallMessageWrapper // provides read/write access to the method // call arguments. MethodCallMessageWrapper mc = new MethodCallMessageWrapper(msgMethodCall); // This is the reflected method base of the called method. MethodInfo mi = (MethodInfo)mc.MethodBase; IMessage retval = null; // Pass the call to the method and get our return value string profileName = ProfileClassName + "." + mi.Name; using (ProfileManager.Start(profileName)) { IMessage myReturnMessage = RemotingServices.ExecuteMessage(_target, msgMethodCall); retval = myReturnMessage; } return retval; } </code></pre> <p>Isn't it fascinating what .NET can do? The only restriction is that the target type <em>must</em> be derived from <strong><em>MarshalByRefObject</em></strong>. I hope this is helpful to someone.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload