Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<h1>Where/when to use interceptors</h1> <p>Take a look at a previous application you've developed and examine the code. Look for code that is frequently duplicated at the beginning or end of methods and properties. This is code that you may consider moving from all of those methods into an interceptor. For example, I've noticed that many of my MVC actions that perform input validation do so with same same couple lines of code:</p> <pre><code>if (!ModelState.IsValid) return View(model); </code></pre> <p>This is code that could potentially be moved to an interceptor (probably an MVC filter in this case). Does the cost of writing and applying the filter outweigh the cost of this duplicated code? (2 lines of code times the number of controller actions using this). In this case, perhaps not. There are other situations, however, where the benefit of using an interceptor would be greater.</p> <p>Here's a list of some situations where I imagine this type of code duplication might occur, i.e. <strong>scenarios that <em>smell</em> like they could benefit from interceptors</strong>:</p> <ul> <li><strong>Input validation</strong> (as illustrated above).</li> <li><strong>Debug logging.</strong> You could <a href="http://ayende.com/blog/3474/logging-the-aop-way" rel="nofollow noreferrer">write an interceptor</a> that records the entrance and exit of every method call.</li> <li><strong>Thread synchronization.</strong> Your question is about web apps, but if you're developing a Windows application with an MVP style view, you could apply an interceptor that ensures that all method calls are synchronized back to the UI thread.</li> <li><strong>Database transactions.</strong> Most of my database transaction code looks like this:</li> </ul> <p>&nbsp;</p> <pre><code>using (var transaction = Session.BeginTransaction()) { // ... do some work that is unique to this method ... transaction.Commit(); } </code></pre> <ul> <li><strong>PropertyChanged event implementations.</strong> This code is usually very repetitive and annoying to write. <a href="http://www.codeproject.com/Articles/140042/Aspect-Examples-INotifyPropertyChanged-via-Aspects" rel="nofollow noreferrer">Sacha Barber has thoroughly explored how to automatically implement this event using various frameworks</a>.</li> <li><strong>Security.</strong> There are probably many methods in your application that should be restricted to only certain users. <a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute.aspx" rel="nofollow noreferrer">The <code>AuthorizeAttribute</code></a> is a filter for exactly this.</li> <li><strong>Web service request throttling.</strong> Some API's, such as the API for Basecamp, ask that you <a href="https://github.com/37signals/bcx-api#rate-limiting" rel="nofollow noreferrer">limit your requests</a> to a certain number of requests per a given timeframe. If you wrote a Basecamp client class, you could apply an interceptor to it to ensure that all the method calls honored the speed limit, using <code>Thread.Sleep</code> when necessary.</li> <li><strong>Result caching.</strong> <a href="http://msdn.microsoft.com/en-us/library/system.web.mvc.outputcacheattribute.aspx" rel="nofollow noreferrer">MVC has some filters pre-built for this purpose</a>. You could write your own interceptor to cache results for layers underneath the UI layer.</li> <li><strong>WCF error handling.</strong> You can't <code>Dispose</code> a WCF client if it's in the <code>Faulted</code> state, so every method that creates and destroys an instance of the client needs to check the state, then call <code>Abort</code> if necessary instead of simply wrapping a <code>using</code> clause around the client. An interceptor might not be the best fit in this case. It's probably easier <a href="http://coding.abel.nu/2012/02/using-and-disposing-of-wcf-clients/" rel="nofollow noreferrer">to just fix the <code>Dispose</code> implementation or use some kind of wrapper</a>.</li> </ul> <p>Whether or not the above examples would be good candidates for interceptors depends on the unique intricacies of your application. This list of course is not exhaustive, nor can it be. The possible applications of interceptors are as varied as the applications you write.</p> <h1>How to use interceptors</h1> <p>I can think of three primary places where you might like to apply an interceptor: Controllers, Services, and Domain objects.</p> <ul> <li>With an <strong>MVC controller</strong>, it makes the most sense to go ahead and use <strong><a href="http://msdn.microsoft.com/en-us/library/gg416513%28v=vs.98%29.aspx" rel="nofollow noreferrer">MVC's filters</a></strong>.</li> <li>For a <strong>middle-tier service</strong> that you would pull out of your IoC container, filters are not an option (because it's not a controller), so you should use the <strong><a href="https://github.com/castleproject/Windsor/blob/master/docs/interceptors.md" rel="nofollow noreferrer">interception features of your IoC container</a></strong>. </li> <li>For your <strong>domain objects</strong> that you typically either instantiate directly with a constructor (if it's a new entity) or fetch from your ORM of choice (if it's an existing entity), you'll need to use some sort of <strong>object factory</strong> instead of the constructor and <a href="http://nhibernate.info/blog/2008/12/12/entities-behavior-injection.html" rel="nofollow noreferrer">instruct your ORM how to use the factory</a>.</li> </ul> <p>The nitty gritty details about how to accomplish all of this will depend on which tools you are using.</p>
 

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