15.01.2013 Views

Foundations of Programming - Karl Seguin

Foundations of Programming - Karl Seguin

Foundations of Programming - Karl Seguin

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Chapter 9 - Back to Basics: Proxy This and Proxy That<br />

Unfortunately, we've had to go to the database twice to load the appropriate SalesPerson and Model<br />

- even though we aren't really using them. The truth is all we need is their ID (since that's what gets<br />

inserted into our database), which we already have.<br />

By creating a proxy, NHibernate lets us fully lazy-load an object for just this type <strong>of</strong> circumstance. The<br />

first thing to do is change our mapping and enable lazy loading <strong>of</strong> both Models and SalesPeoples:<br />

...<br />

...<br />

The proxy attribute tells NHibernate what type should be proxied. This will either be the actual class<br />

you are mapping to, or an interface implemented by the class. Since we are using the actual class as our<br />

proxy interface, we need to make sure all members are virtual - if we miss any, NHibernate will throw a<br />

helpful exception with a list <strong>of</strong> non-virtual methods. Now we're good to go:<br />

Sale sale = new Sale();<br />

sale.SalesPerson = session.Load (1);<br />

sale.Model = session.Load(2);<br />

sale.Price = 25000;<br />

session.Save(sale);<br />

Notice that we're using Load instead <strong>of</strong> Get. The difference between the two is that if you're retrieving<br />

a class that supports lazy loading, Load will get the proxy, while Get will get the actual object. With this<br />

code in place we're no longer hitting the database just to load IDs. Instead, calling<br />

Session.Load(2) returns a proxy - dynamically generated by NHibernate. The proxy will<br />

have an id <strong>of</strong> 2, since we supplied it the value, and all other properties will be uninitialized. Any call to<br />

another member <strong>of</strong> our proxy, such as sale.Model.Name will be transparently intercepted and the<br />

object will be just-in-time loaded from the database.<br />

Just a note, NHibernate's lazy-load behavior can be hard to spot when debugging code in Visual Studio.<br />

That's because VS.NET's watch/local/tooltip actually inspects the object, causing the load to happen<br />

right away. The best way to examine what's going on is to add a couple breakpoints around your code<br />

and check out the database activity either through NHibernate's log, or SQL pr<strong>of</strong>iler.<br />

Hopefully you can imagine how proxies are used by RhinoMocks for recording, replaying and verifying<br />

interactions. When you create a partial you're really creating a proxy to your actual object. This proxy<br />

intercepts all calls, and depending on which state you are, does its own thing. Of course, for this to work,<br />

you must either mock an interface, or a virtual members <strong>of</strong> a class.<br />

<strong>Foundations</strong> <strong>of</strong> <strong>Programming</strong> Copyright © <strong>Karl</strong> <strong>Seguin</strong> www.codebetter.com<br />

76

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!