<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
><channel><title>The Inquisitive Coder - Davy Brion&#039;s Blog &#187; PostSharp</title> <atom:link href="http://davybrion.com/blog/category/postsharp/feed/" rel="self" type="application/rss+xml" /><link>http://davybrion.com/blog</link> <description>inquisitive: adjective. given to inquiry, research, or asking questions; eager for knowledge; intellectually curious</description> <lastBuildDate>Mon, 14 May 2012 21:08:36 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.2</generator> <item><title>NHibernate and virtual methods/properties</title><link>http://davybrion.com/blog/2008/05/nhibernate-and-virtual-methodsproperties/</link> <comments>http://davybrion.com/blog/2008/05/nhibernate-and-virtual-methodsproperties/#comments</comments> <pubDate>Sat, 24 May 2008 13:54:44 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[NHibernate]]></category> <category><![CDATA[PostSharp]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=123</guid> <description><![CDATA[I love NHibernate but one of the things that bothers the hell out of me is that i keep forgetting to add the virtual keyword to each method or property in my entities. And since NHibernate needs your classes' properties and methods to be virtual, this causes run-time errors when i run my tests. Since [...]]]></description> <content:encoded><![CDATA[<p>I love NHibernate but one of the things that bothers the hell out of me is that i keep forgetting to add the virtual keyword to each method or property in my entities.  And since NHibernate needs your classes' properties and methods to be virtual, this causes run-time errors when i run my tests. Since i'm already using <a
href="http://davybrion.com/blog/2008/05/creating-sanity-checks/">custom compile time checks</a>, i figured i might as well add another one... from now on, i want my compilation to fail if any of my NHibernate entities have public methods/properties that aren't marked virtual.</p><p>Once again, it's PostSharp to the rescue:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;"><span
style="color: blue;">using</span> System;</p><p
style="margin: 0px;"><span
style="color: blue;">using</span> System.Reflection;</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;"><span
style="color: blue;">using</span> PostSharp.Extensibility;</p><p
style="margin: 0px;"><span
style="color: blue;">using</span> PostSharp.Laos;</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;"><span
style="color: blue;">namespace</span> Northwind.Aspects</p><p
style="margin: 0px;">{</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">Serializable</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">AttributeUsage</span>(<span
style="color: #2b91af;">AttributeTargets</span>.Assembly | <span
style="color: #2b91af;">AttributeTargets</span>.Method | <span
style="color: #2b91af;">AttributeTargets</span>.Property)]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">MulticastAttributeUsage</span>(<span
style="color: #2b91af;">MulticastTargets</span>.Method, TargetMemberAttributes = <span
style="color: #2b91af;">MulticastAttributes</span>.Managed |</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">MulticastAttributes</span>.NonAbstract | <span
style="color: #2b91af;">MulticastAttributes</span>.Instance |</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">MulticastAttributes</span>.Protected | <span
style="color: #2b91af;">MulticastAttributes</span>.Public)]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">RequireVirtualMethodsAndProperties</span> : <span
style="color: #2b91af;">OnMethodBoundaryAspect</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">override</span> <span
style="color: blue;">bool</span> CompileTimeValidate(<span
style="color: #2b91af;">MethodBase</span> method)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">if</span> (!method.IsVirtual)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">string</span> methodName = method.DeclaringType.FullName + <span
style="color: #a31515;">"."</span> + method.Name;</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> message = <span
style="color: blue;">new</span> <span
style="color: #2b91af;">Message</span>(<span
style="color: #2b91af;">SeverityType</span>.Fatal, <span
style="color: #a31515;">"MustBeVirtual"</span>,</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">string</span>.Format(<span
style="color: #a31515;">"{0} must be virtual"</span>, methodName), GetType().Name);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">MessageSource</span>.MessageSink.Write(message);</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> <span
style="color: blue;">false</span>;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> <span
style="color: blue;">true</span>;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">}</p></div><p></code></p><p>And then we make sure this check is applied to my NHibernate entities:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;"><span
style="color: blue;">#if</span> DEBUG</p><p
style="margin: 0px;">[<span
style="color: blue;">assembly</span>: <span
style="color: #2b91af;">RequireVirtualMethodsAndProperties</span>(AttributeTargetTypes = <span
style="color: #a31515;">"Northwind.Domain.Entities.*"</span>)]</p><p
style="margin: 0px;"><span
style="color: blue;">#endif</span></p></div><p></code></p><p>Now, whenever i forget to mark my properties/methods as virtual, i get this:</p><p><code> EXEC : error MustBeVirtual: Northwind.Domain.Entities.Region.RemoveTerritory must be virtual
EXEC : error MustBeVirtual: Northwind.Domain.Entities.Region.AddTerritory must be virtual
EXEC : error MustBeVirtual: Northwind.Domain.Entities.Region.get_Territories must be virtual
EXEC : error MustBeVirtual: Northwind.Domain.Entities.Region.set_Description must be virtual
EXEC : error MustBeVirtual: Northwind.Domain.Entities.Region.get_Description must be virtual
EXEC : error MustBeVirtual: Northwind.Domain.Entities.Region.set_Id must be virtual
EXEC : error MustBeVirtual: Northwind.Domain.Entities.Region.get_Id must be virtual</p><p>...</p><p>Done building project "Northwind.csproj" -- FAILED. </code></p><p>And there we go <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2008%2F05%2Fnhibernate-and-virtual-methodsproperties%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2008/05/nhibernate-and-virtual-methodsproperties/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2008/05/nhibernate-and-virtual-methodsproperties/"  data-text="NHibernate and virtual methods/properties" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2008/05/nhibernate-and-virtual-methodsproperties/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2008/05/nhibernate-and-virtual-methodsproperties/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2008/05/nhibernate-and-virtual-methodsproperties/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Creating Sanity Checks</title><link>http://davybrion.com/blog/2008/05/creating-sanity-checks/</link> <comments>http://davybrion.com/blog/2008/05/creating-sanity-checks/#comments</comments> <pubDate>Sat, 24 May 2008 07:30:59 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[PostSharp]]></category> <category><![CDATA[Software Development]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=122</guid> <description><![CDATA[Ever been in a situation where you notice that one of the team-members used classes from an assembly that really shouldn't be used in that part of the code? For instance, accessing the data layer from the presentation layer. It's not always easy to keep an eye on improper assembly usage. You could keep an [...]]]></description> <content:encoded><![CDATA[<p>Ever been in a situation where you notice that one of the team-members used classes from an assembly that really shouldn't be used in that part of the code? For instance, accessing the data layer from the presentation layer. It's not always easy to keep an eye on improper assembly usage. You could keep an eye on the referenced assemblies manually. You could write an FxCop rule that checks for disallowed assembly references.  There's a lot of stuff you can do, but it'll always be an after-the-facts check. By that time, the 'illegal' code is already there.</p><p>Wouldn't it be cool if you could break the compilation whenever a developer tries to build code that has improper assembly usage? Actually, with PostSharp, we can do just that.  You can simply create an aspect like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">Serializable</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">AttributeUsage</span>(<span
style="color: #2b91af;">AttributeTargets</span>.Assembly)]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">SanityCheck</span> : <span
style="color: #2b91af;">OnMethodInvocationAspect</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">override</span> <span
style="color: blue;">bool</span> CompileTimeValidate(System.Reflection.<span
style="color: #2b91af;">MethodBase</span> method)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> methodName = method.DeclaringType.FullName + <span
style="color: #a31515;">"."</span> + method.Name;</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> message = <span
style="color: blue;">new</span> <span
style="color: #2b91af;">Message</span>(<span
style="color: #2b91af;">SeverityType</span>.Fatal, <span
style="color: #a31515;">"ProhibitedMethodCall"</span>, <span
style="color: #2b91af;">String</span>.Format(</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #a31515;">"Sorry, but we can't allow you to call {0} from the current assembly"</span>, methodName),</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #a31515;">"SanityCheck"</span>);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">MessageSource</span>.MessageSink.Write(message);</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> <span
style="color: blue;">false</span>;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>First of all, we declare that the SanityCheck attribute can only be applied on the assembly level. Notice that we inherit from OnMethodInvocationAspect. This aspect is applied on events, properties, and methods. So basically, whenever you call a property or method or try to hook to an event in an assembly that you've applied this attribute to, our SanityCheck aspect will run.  Well, actually we won't get that far. We override the virtual CompileTimeValidate method where we display a message and then we return false. Meaning that this compilation is invalid.</p><p>Suppose you've used the attribute in the AssemblyInfo.cs file of your presentation layer like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">[<span
style="color: blue;">assembly</span>: <span
style="color: #2b91af;">SanityCheck</span>(AttributeTargetAssemblies = <span
style="color: #a31515;">"System.Data"</span>)]</p></div><p></code></p><p>If you try to compile the following code:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">DataTable</span> table = <span
style="color: blue;">new</span> <span
style="color: #2b91af;">DataTable</span>();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; table.NewRow();</p></div><p></code></p><p>You'll see the following line in your build output:</p><p><code></p><p>EXEC : error ProhibitedMethodCall: Sorry, but we can't allow you to call System.Data.DataTable.NewRow from the current assembly</p><p></code></p><p>And most importantly:</p><p><code></p><p>========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped ==========</p><p></code></p><p>Obviously, this will only cause compile errors when you try to touch the prohibited parts within the assembly where you used the SanityCheck attribute.  If you call a method in another assembly that is allowed to touch System.Data, it will not cause a compile error.</p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2008%2F05%2Fcreating-sanity-checks%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2008/05/creating-sanity-checks/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2008/05/creating-sanity-checks/"  data-text="Creating Sanity Checks" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2008/05/creating-sanity-checks/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2008/05/creating-sanity-checks/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2008/05/creating-sanity-checks/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>WCF Exception Handling with PostSharp</title><link>http://davybrion.com/blog/2008/05/wcf-exception-handling-with-postsharp/</link> <comments>http://davybrion.com/blog/2008/05/wcf-exception-handling-with-postsharp/#comments</comments> <pubDate>Fri, 23 May 2008 09:37:55 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Aspect Oriented Programming]]></category> <category><![CDATA[PostSharp]]></category> <category><![CDATA[WCF]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=120</guid> <description><![CDATA[In your WCF service methods, you should always provide proper exception handling. The exception handling code is almost always the same, so it's usually just copy/pasted in each method. Here's an example of a typical service method: &#160;&#160;&#160; &#160;&#160;&#160; public void PersistOrder(Order order) &#160;&#160;&#160; &#160;&#160;&#160; { &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; try &#160;&#160;&#160; &#160;&#160;&#160; &#160;&#160;&#160; { &#160;&#160;&#160; [...]]]></description> <content:encoded><![CDATA[<p>In your WCF service methods, you should always provide proper exception handling. The exception handling code is almost always the same, so it's usually just copy/pasted in each method. Here's an example of a typical service method:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">void</span> PersistOrder(<span
style="color: #2b91af;">Order</span> order)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">try</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Container</span>.Resolve&lt;<span
style="color: #2b91af;">IPersistOrderHandler</span>&gt;().Handle(order);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">catch</span> (<span
style="color: #2b91af;">BusinessException</span> b)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">throw</span> <span
style="color: blue;">new</span> <span
style="color: #2b91af;">FaultException</span>&lt;<span
style="color: #2b91af;">BusinessExceptionInformation</span>&gt;(<span
style="color: blue;">new</span> <span
style="color: #2b91af;">BusinessExceptionInformation</span>(b),</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">new</span> <span
style="color: #2b91af;">FaultReason</span>(b.Message));&nbsp;&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">catch</span> (<span
style="color: #2b91af;">FaultException</span>)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">throw</span>;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">catch</span> (<span
style="color: #2b91af;">Exception</span> e)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Container</span>.Resolve&lt;<span
style="color: #2b91af;">ILogger</span>&gt;().LogException(e);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">throw</span> <span
style="color: blue;">new</span> <span
style="color: #2b91af;">FaultException</span>(<span
style="color: blue;">new</span> <span
style="color: #2b91af;">FaultReason</span>(e.Message));</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>That's a lot of code, even though only ONE line will differ from the other service methods in this service.  Let's clean up this mess, shall we? Exception handling is a <a
href="http://en.wikipedia.org/wiki/Cross-cutting_concern">cross cutting concern</a> so we might as well put it in one place (at least, one place for each different kind of exception handling that you need).  We'll use PostSharp to define an ApplyServiceExceptionHandling aspect:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">Serializable</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">ApplyServiceExceptionHandling</span> : <span
style="color: #2b91af;">OnExceptionAspect</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">override</span> <span
style="color: blue;">void</span> OnException(<span
style="color: #2b91af;">MethodExecutionEventArgs</span> eventArgs)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">if</span> (eventArgs.Exception <span
style="color: blue;">is</span> <span
style="color: #2b91af;">BusinessException</span>)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">throw</span> <span
style="color: blue;">new</span> <span
style="color: #2b91af;">FaultException</span>&lt;<span
style="color: #2b91af;">BusinessExceptionInformation</span>&gt;(</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">new</span> <span
style="color: #2b91af;">BusinessExceptionInformation</span>(eventArgs.Exception <span
style="color: blue;">as</span> <span
style="color: #2b91af;">BusinessException</span>),</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">new</span> <span
style="color: #2b91af;">FaultReason</span>(eventArgs.Exception.Message));</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">else</span> <span
style="color: blue;">if</span> (eventArgs.Exception <span
style="color: blue;">is</span> <span
style="color: #2b91af;">FaultException</span>)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; eventArgs.FlowBehavior = <span
style="color: #2b91af;">FlowBehavior</span>.RethrowException;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">else</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Container</span>.Resolve&lt;<span
style="color: #2b91af;">ILogger</span>&gt;().LogException(eventArgs.Exception);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">throw</span> <span
style="color: blue;">new</span> <span
style="color: #2b91af;">FaultException</span>(<span
style="color: blue;">new</span> <span
style="color: #2b91af;">FaultReason</span>(eventArgs.Exception.Message));</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>And now we can modify the earlier service method to this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">ApplyServiceExceptionHandling</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">void</span> PersistOrder(<span
style="color: #2b91af;">Order</span> order)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Container</span>.Resolve&lt;<span
style="color: #2b91af;">IPersistOrderHandler</span>&gt;().Handle(order);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>That's a lot cleaner than the previous version right? Actually, this service has more than one service method so we're better off moving the ApplyServiceExceptionHandling attribute to the class level instead of the method level:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">ApplyServiceExceptionHandling</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">OrderManagementService</span> : <span
style="color: #2b91af;">IOrderManagementService</span></p></div><p></code></p><p>now we can get rid of all of the exception handling code in each service method, but each one will have exception handling applied to it because the exception handling aspect is applied to the class, and thus, to each method of that class.  And if you need to modify your exception handling (to handle TargetInvocationExceptions with BusinessExceptions as InnerExceptions for instance?) you'd only have to do this in one place.</p><p>Btw, i'm aware of WCF's IErrorHandler interface (which allows you to handle exceptions in a general manner as well)... i just don't like it <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2008%2F05%2Fwcf-exception-handling-with-postsharp%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2008/05/wcf-exception-handling-with-postsharp/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2008/05/wcf-exception-handling-with-postsharp/"  data-text="WCF Exception Handling with PostSharp" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2008/05/wcf-exception-handling-with-postsharp/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2008/05/wcf-exception-handling-with-postsharp/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2008/05/wcf-exception-handling-with-postsharp/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Adding Behavior With PostSharp</title><link>http://davybrion.com/blog/2008/05/adding-behavior-with-postsharp/</link> <comments>http://davybrion.com/blog/2008/05/adding-behavior-with-postsharp/#comments</comments> <pubDate>Wed, 21 May 2008 20:12:41 +0000</pubDate> <dc:creator>Davy Brion</dc:creator> <category><![CDATA[Aspect Oriented Programming]]></category> <category><![CDATA[PostSharp]]></category> <category><![CDATA[Software Development]]></category><guid
isPermaLink="false">http://davybrion.com/blog/?p=118</guid> <description><![CDATA[A little while ago, i talked about adding behavior to components using Windsor's Interceptors. I wanted to try something similar with PostSharp, which is a very powerful Aspect Oriented Programming framework for the .NET world. Discussing everything PostSharp can do (which is a lot) is way beyond the scope of this post, so we'll just [...]]]></description> <content:encoded><![CDATA[<p>A little while ago, i talked about <a
href="http://davybrion.com/blog/2008/05/adding-behavior-without-modifying-existing-code-with-windsor/">adding behavior to components using Windsor's Interceptors</a>.  I wanted to try something similar with <a
href="http://www.postsharp.org/">PostSharp</a>, which is a very powerful <a
href="http://en.wikipedia.org/wiki/Aspect-Oriented_Programming">Aspect Oriented Programming</a> framework for the .NET world.  Discussing everything PostSharp can do (which is <strong>a lot</strong>) is way beyond the scope of this post, so we'll just focus on what i'm trying to do, and how PostSharp helps us with that.</p><p>In the previous post, i used a logging example... i didn't want logging code mixed up with my real code, so i used a Windsor Interceptor to intercept calls to classes that i had configured to be logged.  The interceptor would then log before and after the method calls were executed.  In this post we'll do something very similar, but a bit more advanced.  We're gonna write some tracing logic that will write a trace statement when the method is entered, along with the parameter values for each of its parameters.  Then after the original method has executed, we'll write a trace statement to indicate that we have left the method, and we'll display the return value of the method as well, if there is one. That kind of tracing information can be very valuable, but writing that code is extremely tedious work.  Nobody wants to do that, right? I sure as hell don't.</p><p>We'll use the following simple class as an example:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">Calculator</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">int</span> Add(<span
style="color: blue;">int</span> firstValue, <span
style="color: blue;">int</span> secondValue)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> firstValue + secondValue;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">int</span> Subtract(<span
style="color: blue;">int</span> firstValue, <span
style="color: blue;">int</span> secondValue)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> firstValue - secondValue;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>This calculator has a pretty limited feature-set, but we don't need anything more for this example. Ok, so how do we add the tracing code without actually adding it to this code? We can just compile the code, and then we can have PostSharp inject some extra code to the compiled code.  Sounds pretty hard, right? It is. But PostSharp Laos is a small framework that runs on top of PostSharp and it takes care of the hard work for you.  PostSharp Laos offers some base classes which make it really easy for you to write your aspects (if you don't understand that term, you should have clicked on the aspect oriented programming link earlier in the post <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ).  There are a couple of approaches you can choose between, and they all have their pro's and con's.  A nice overview of the different kinds of aspects you can inherit from can be found <a
href="http://doc.postsharp.org/1.0/UserGuide/Laos/AspectKinds/Overview.html">here</a>.  For this example, we'll use the OnMethodInvocationAspect base class. This basically intercepts calls to methods and allows you to add some logic.</p><p>So what would our tracing aspect look like? How about this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">Serializable</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">TraceAspect</span> : <span
style="color: #2b91af;">OnMethodInvocationAspect</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">override</span> <span
style="color: blue;">void</span> OnInvocation(<span
style="color: #2b91af;">MethodInvocationEventArgs</span> eventArgs)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">string</span> methodName = GetFullMethodName(eventArgs);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WriteOutput(<span
style="color: #2b91af;">String</span>.Format(<span
style="color: #a31515;">"Entering {0}"</span>, methodName));</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WriteParameterInfo(eventArgs.Delegate.Method.GetParameters(), eventArgs.GetArgumentArray());</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">base</span>.OnInvocation(eventArgs); <span
style="color: green;">// calls the original method</span></p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WriteOutput(<span
style="color: #2b91af;">String</span>.Format(<span
style="color: #a31515;">"Leaving {0}"</span>, methodName));</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WriteReturnValueInfo(eventArgs.Delegate.Method.ReturnType, eventArgs.ReturnValue);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: blue;">static</span> <span
style="color: blue;">void</span> WriteParameterInfo(<span
style="color: #2b91af;">ParameterInfo</span>[] parameterInfos, <span
style="color: blue;">object</span>[] parameters)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">if</span> (parameterInfos == <span
style="color: blue;">null</span> || parameterInfos.Length == 0)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span>;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WriteOutput(<span
style="color: #a31515;">"With the following parameters: "</span>);</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">for</span> (<span
style="color: blue;">int</span> i = 0; i &lt; parameterInfos.Length; i++)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WriteOutput(<span
style="color: blue;">string</span>.Format(<span
style="color: #a31515;">"{0} = {1}"</span>, parameterInfos[i].Name, parameters[i]));</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: blue;">static</span> <span
style="color: blue;">void</span> WriteReturnValueInfo(<span
style="color: #2b91af;">Type</span> returnType, <span
style="color: blue;">object</span> returnValue)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">if</span> (returnType == <span
style="color: blue;">typeof</span>(<span
style="color: blue;">void</span>))</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span>;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; WriteOutput(<span
style="color: blue;">string</span>.Format(<span
style="color: #a31515;">"Return Value: {0}"</span>, returnValue));&nbsp;&nbsp;&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: blue;">static</span> <span
style="color: blue;">string</span> GetFullMethodName(<span
style="color: #2b91af;">MethodInvocationEventArgs</span> args)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">return</span> args.Delegate.Target.GetType().FullName + <span
style="color: #a31515;">"."</span> + args.Delegate.Method.Name;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">private</span> <span
style="color: blue;">static</span> <span
style="color: blue;">void</span> WriteOutput(<span
style="color: blue;">string</span> line)</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: #2b91af;">Trace</span>.WriteLine(<span
style="color: #2b91af;">DateTime</span>.Now.TimeOfDay + <span
style="color: #a31515;">" "</span> + line);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; }</p></div><p></code></p><p>So now we have a trace aspect which shows some valuable information about method calls... it shows when the method is entered, which parameters were passed in, when we leave the method and what the return value is.</p><p>So how do we apply this aspect to our code? We modify the definition of the Calculator class like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; [<span
style="color: #2b91af;">TraceAspect</span>]</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; <span
style="color: blue;">public</span> <span
style="color: blue;">class</span> <span
style="color: #2b91af;">Calculator</span></p></div><p></code></p><p>And then we compile... Well actually you have to add something to your project file so PostSharp can modify the compiled code, but since that's covered nicely in the PostSharp documentation we'll skip that step in this post.  Anyways, when you compile this, you'll get the following build output:</p><p><code></p><p>------ Build started: Project: UsingPostSharp, Configuration: Debug Any CPU ------
C:\WINDOWS\Microsoft.NET\Framework\v3.5\Csc.exe /noconfig /nowarn:1701,1702 /errorreport:prompt /warn:4 /define:POSTSHARP;DEBUG;TRACE /reference:..\Libs\postsharp\PostSharp.Laos.dll /reference:..\Libs\postsharp\PostSharp.Public.dll /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll" /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Data.DataSetExtensions.dll" /reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /reference:"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll" /debug+ /debug:full /filealign:512 /optimize- /out:obj\Debug\UsingPostSharp.exe /target:exe Program.cs Properties\AssemblyInfo.cs TraceAspect.cs</p><p>Compile complete -- 0 errors, 0 warnings <strong>"C:\mydocs\src\dbr\Experiments\UsingPostSharp\Libs\postsharp\PostSharp.exe"  "C:\mydocs\src\dbr\Experiments\UsingPostSharp\Libs\postsharp\Default.psproj" "C:\mydocs\src\dbr\Experiments\UsingPostSharp\UsingPostSharp\obj\Debug\UsingPostSharp.exe" "/P:Output=obj\Debug\PostSharp\UsingPostSharp.exe " "/P:ReferenceDirectory=C:\mydocs\src\dbr\Experiments\UsingPostSharp\UsingPostSharp " "/P:Configuration=Debug " "/P:Platform=AnyCPU " "/P:SearchPath=bin\Debug\, " "/P:IntermediateDirectory=obj\Debug\PostSharp " "/P:CleanIntermediate=False " "/P:MSBuildProjectFullPath=C:\mydocs\src\dbr\Experiments\UsingPostSharp\UsingPostSharp\UsingPostSharp.csproj " "/P:SignAssembly=False " "/P:PrivateKeyLocation= "
PostSharp 1.0 [1.0.9.365] - Copyright (c) Gael Fraiteur, 2005-2008.</p><p>info PS0035: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ilasm.exe "C:\mydocs\src\dbr\Experiments\UsingPostSharp\UsingPostSharp\obj\Debug\PostSharp\UsingPostSharp.il" /QUIET /EXE /PDB "/RESOURCE=C:\mydocs\src\dbr\Experiments\UsingPostSharp\UsingPostSharp\obj\Debug\PostSharp\UsingPostSharp.res" "/OUTPUT=C:\mydocs\src\dbr\Experiments\UsingPostSharp\UsingPostSharp\obj\Debug\PostSharp\UsingPostSharp.exe" /SUBSYSTEM=3 /FLAGS=1 /BASE=4194304 /STACK=1048576 /ALIGNMENT=512 /MDV=v2.0.50727
UsingPostSharp -> C:\mydocs\src\dbr\Experiments\UsingPostSharp\UsingPostSharp\bin\Debug\UsingPostSharp.exe</strong> ========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========</p><p></code></p><p>If we use the calculator class like this:</p><p><code></p><div
style="font-family: Consolas; font-size: 10pt; color: black; background: white;"><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span
style="color: blue;">var</span> calculator = <span
style="color: blue;">new</span> <span
style="color: #2b91af;">Calculator</span>();</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; calculator.Add(10, 15);</p><p
style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; calculator.Subtract(10, 15);</p></div><p></code></p><p>We'll get the following trace output:</p><p><code></p><p>21:48:49.9414848 Entering UsingPostSharp.Calculator.~Add
21:48:49.9615136 With the following parameters:
21:48:49.9615136 firstValue = 10
21:48:49.9615136 secondValue = 15
21:48:49.9615136 Leaving UsingPostSharp.Calculator.~Add
21:48:49.9615136 Return Value: 25
21:48:49.9615136 Entering UsingPostSharp.Calculator.~Subtract
21:48:49.9615136 With the following parameters:
21:48:49.9615136 firstValue = 10
21:48:49.9615136 secondValue = 15
21:48:49.9615136 Leaving UsingPostSharp.Calculator.~Subtract
21:48:49.9615136 Return Value: -5</p><p></code></p><p>How nice is that? With some exception handling, better formatting and some clever indenting, this tracing aspect could be the only tracing code you'll ever need from now on <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>So how does it work? Well, we can look at the compiled code in reflector for that.  Here's how the Add method looks like after PostSharp modified the code:</p><p><code></p><pre><code>private int ~Add(int firstValue, int secondValue)
{
    return (firstValue + secondValue);
}

[DebuggerNonUserCode, CompilerGenerated]
public int Add(int firstValue, int secondValue)
{
    Delegate delegateInstance = new ~PostSharp~Laos~Implementation.~delegate~0(this.~Add);
    object[] arguments = new object[] { firstValue, secondValue };
    MethodInvocationEventArgs eventArgs = new MethodInvocationEventArgs(delegateInstance, arguments);
    ~PostSharp~Laos~Implementation.TraceAspect~1.OnInvocation(eventArgs);
    return (int) eventArgs.ReturnValue;
}
</code></pre><p></code></p><p>As you can see, it's renamed our Add method to ~Add, and it added another Add method which calls the OnInvocation method of our TraceAspect class with the correct MethodInvocationEventArgs.  Pretty cool stuff IMO.  Oh and btw, if you're debugging this code in Visual Studio, you still only see your own code, with the original method name.  While you step through it, the code runs just like it normally would, and the applied aspects are also executed. Very impressive.</p><p>If you use the OnMethodBoundaryAspect instead of the OnMethodInvocationAspect, you'll see that the modified code doesn't replace your method like it did here.  But it will add a lot of extra code to it as well.  All in all, there are a lot of possibilities here.  If i'm not mistaken, i can now even use our TraceAspect and use it on classes in other assemblies, even if i don't have access to them.  We'll look into that in a future post <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>Anyway, PostSharp is an extremely impressive piece of software which provides a whole lot of power and flexibility. You should definitely check it out and play around with it... i know i'm gonna be experimenting with it more often to see what kind of weird and cool stuff we can make it do <img
src='http://d18sni7re4ly7f.cloudfront.net/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><div
class="bottomcontainerBox" style=""><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <iframe
src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Fdavybrion.com%2Fblog%2F2008%2F05%2Fadding-behavior-with-postsharp%2F&amp;layout=button_count&amp;show_faces=false&amp;width=85&amp;action=like&amp;font=verdana&amp;colorscheme=light&amp;height=21" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:85px; height:21px;"></iframe></div><div
style="float:left; width:80px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <g:plusone size="medium" href="http://davybrion.com/blog/2008/05/adding-behavior-with-postsharp/"></g:plusone></div><div
style="float:left; width:95px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"> <a
href="http://twitter.com/share" class="twitter-share-button" data-url="http://davybrion.com/blog/2008/05/adding-behavior-with-postsharp/"  data-text="Adding Behavior With PostSharp" data-count="horizontal" data-via="davybrion"></a></div><div
style="float:left; width:105px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script type="in/share" data-url="http://davybrion.com/blog/2008/05/adding-behavior-with-postsharp/" data-counter="right"></script></div><div
style="float:left; width:85px;padding-right:10px; margin:4px 4px 4px 4px;height:30px;"><script src="http://www.stumbleupon.com/hostedbadge.php?s=1&amp;r=http://davybrion.com/blog/2008/05/adding-behavior-with-postsharp/"></script></div></div><div
style="clear:both"></div><div
style="padding-bottom:4px;"></div>]]></content:encoded> <wfw:commentRss>http://davybrion.com/blog/2008/05/adding-behavior-with-postsharp/feed/</wfw:commentRss> <slash:comments>7</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 1/23 queries in 0.012 seconds using disk: basic
Object Caching 594/630 objects using disk: basic
Content Delivery Network via Amazon Web Services: CloudFront: d18sni7re4ly7f.cloudfront.net

Served from: davybrion.com @ 2012-05-23 14:13:14 -->
