<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>PostSharp Official Blog</title><link>http://www.sharpcrafters.com/blog/</link><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/postsharp" /><description>News, tips and tricks from PostSharp</description><language>en-US</language><managingEditor>noemail@noemail.org (Gael Fraiteur)</managingEditor><generator>BlogEngine.NET 1.6.0.0</generator><blogChannel:blogRoll xmlns:blogChannel="http://backend.userland.com/blogChannelModule">http://www.sharpcrafters.com/blog/opml.axd</blogChannel:blogRoll><blogChannel:blink xmlns:blogChannel="http://backend.userland.com/blogChannelModule">http://www.dotnetblogengine.net/syndication.axd</blogChannel:blink><dc:title xmlns:dc="http://purl.org/dc/elements/1.1/">SharpCrafters Blog</dc:title><geo:lat xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">0.000000</geo:lat><geo:long xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">0.000000</geo:long><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/postsharp" /><feedburner:info uri="postsharp" /><thespringbox:skin xmlns:thespringbox="http://www.thespringbox.com/dtds/thespringbox-1.0.dtd">http://feeds.feedburner.com/postsharp?format=skin</thespringbox:skin><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>postsharp</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fpostsharp" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fpostsharp" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2Fpostsharp" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/postsharp" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fpostsharp" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fpostsharp" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fpostsharp" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><item><title>Webinar: How to Stay DRY with AOP and PostSharp – with Video and Q&amp;A!</title><link>http://feedproxy.google.com/~r/postsharp/~3/3HDdxNUenbA/post.aspx</link><category>Webinars</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Gael Fraiteur</dc:creator><pubDate>Fri, 27 Jan 2012 05:20:47 PST</pubDate><guid isPermaLink="false">http://www.sharpcrafters.com/blog/post.aspx?id=1a09389a-c272-4270-9a77-188e87359e9f</guid><description>&lt;p&gt;Wow! What a turnout for my first webinar! Thank you all for attending, I had a great time presenting it, and will continue to do more webinars in the future. The webinar was recorded, and the video is now online for your viewing:&lt;/p&gt; &lt;iframe height="460" src="http://player.vimeo.com/video/35741077?title=0&amp;amp;byline=0&amp;amp;portrait=0&amp;amp;color=01AAEA" frameborder="0" width="640" webkitallowfullscreen="webkitallowfullscreen" mozallowfullscreen="mozallowfullscreen" allowfullscreen="allowfullscreen"&gt;&lt;/iframe&gt;  &lt;p&gt;As promised, here are the answers to the great questions you asked, which I didn’t have the chance to answer during the live webinar. As always, you can always ask your questions on our &lt;a href="http://www.sharpcrafters.com/forum/"&gt;Support Forums&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Q: Any reason the [aspect] class must be Serializable?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; At (post) compilation, the aspect is serialized using binary serialization, and added as a resource to the target process. Then at runtime, the aspect is deserialized. PostSharp will emit a compilation error if you forget to mark your aspect as Serializable.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Q: What is the typical use case for creating interfaces using PostSharp?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; One typical scenario for implementing interfaces with PostSharp is implementing &lt;a href="http://www.sharpcrafters.com/solutions/notifypropertychanged"&gt;&lt;code&gt;INotifyPropertyChanged&lt;/code&gt;&lt;/a&gt; in WPF to support Data Binding.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Q: Are the OnExit and OnEnter aspects thread safe? How would one make it thread safe if it is not?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; While the aspects themselves are thread-safe, shared state (i.e. custom fields) within the aspects is not. To safely pass data around between OnEnter and OnExit events, you can use the &lt;a href="http://doc.sharpcrafters.com/postsharp-2.1/Default.aspx##PostSharp-2.1.chm/html/P_PostSharp_Aspects_MethodExecutionArgs_MethodExecutionTag.htm"&gt;&lt;code&gt;MethodExecutionArgs.MethodExecutionTag&lt;/code&gt;&lt;/a&gt;&lt;strong&gt;&amp;#160;&lt;/strong&gt;property.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Q: What about signed DLLs and PostSharp?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; PostSharp has no problems with signed DLLs – they will be re-signed after the post-compilation process.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Q: What about Silverlight DLL's, is it also available?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;A: &lt;/strong&gt;Of course, PostSharp comes with the Silverlight assemblies included, you need to add a reference to the &lt;em&gt;PostSharp.SL.dll&lt;/em&gt; instead of &lt;em&gt;PostSharp.dll&lt;/em&gt;. For more information, please refer to the &lt;a href="http://doc.sharpcrafters.com/postsharp-2.1/Default.aspx##PostSharp-2.1.chm/html/695ec9f3-577a-4175-8cba-c00d0cb6e47c.htm"&gt;online documentation&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Q: Can you provide a good definition of aspect oriented programming?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Aspect Oriented Programming complements traditional OOP by allowing us to encapsulate infrastructure code (such as logging, security, validation, etc.) into small modules called &lt;em&gt;aspects&lt;/em&gt;, and then &lt;em&gt;apply&lt;/em&gt; those aspects throughout the entire system in such way that the business logic is completely separated from those concerns.&lt;/p&gt;  &lt;p&gt;So go ahead, download the &lt;a href="http://www.sharpcrafters.com/postsharp/download"&gt;free starter edition&lt;/a&gt; now!&lt;/p&gt;  &lt;p&gt;Happy PostSharping!&lt;/p&gt;  &lt;p&gt;-Igal&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=3HDdxNUenbA:3130r3Fa5EA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=3HDdxNUenbA:3130r3Fa5EA:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=3HDdxNUenbA:3130r3Fa5EA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=3HDdxNUenbA:3130r3Fa5EA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=3HDdxNUenbA:3130r3Fa5EA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=3HDdxNUenbA:3130r3Fa5EA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=3HDdxNUenbA:3130r3Fa5EA:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=3HDdxNUenbA:3130r3Fa5EA:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=3HDdxNUenbA:3130r3Fa5EA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=3HDdxNUenbA:3130r3Fa5EA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=3HDdxNUenbA:3130r3Fa5EA:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=3HDdxNUenbA:3130r3Fa5EA:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/postsharp/~4/3HDdxNUenbA" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Gael Fraiteur</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/post.aspx?id=1a09389a-c272-4270-9a77-188e87359e9f</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">4</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.sharpcrafters.com/blog/trackback.axd?id=1a09389a-c272-4270-9a77-188e87359e9f</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/post/Stay-DRY-Webinar.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/syndication.axd?post=1a09389a-c272-4270-9a77-188e87359e9f</wfw:commentRss><feedburner:origLink>http://www.sharpcrafters.com/blog/post.aspx?id=1a09389a-c272-4270-9a77-188e87359e9f</feedburner:origLink></item><item><title>Live Webinar: How to Stay DRY with AOP and PostSharp</title><link>http://feedproxy.google.com/~r/postsharp/~3/jq-Jtzn9fOs/post.aspx</link><category>Webinars</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Igal Tabachnik</dc:creator><pubDate>Tue, 17 Jan 2012 08:46:09 PST</pubDate><guid isPermaLink="false">http://www.sharpcrafters.com/blog/post.aspx?id=2b69a490-c30f-4864-ad36-fdfe9dfd861d</guid><description>&lt;p&gt;Boilerplate code. It’s all around us, polluting our business logic, and forcing us to write the same code over and over again. Join us on Thursday, January 26th, as our very own &lt;a href="http://www.sharpcrafters.com/company"&gt;Igal Tabachnik&lt;/a&gt; shows you how to stay DRY (Don’t-Repeat-Yourself) by using aspect-oriented programming (AOP) and &lt;a href="http://www.sharpcrafters.com/"&gt;PostSharp&lt;/a&gt; to remove boilerplate code that’s duplicated in and across systems.     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;Attendees will learn: &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Why the DRY principle matters &lt;/li&gt;    &lt;li&gt;How AOP helps to remove boilerplate code &lt;/li&gt;    &lt;li&gt;How to use PostSharp to produce cleaner code &lt;/li&gt;    &lt;li&gt;Real-world AOP usage examples &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Oh, and that’s not all – we’re giving away &lt;strong&gt;&lt;em&gt;two&lt;/em&gt;&lt;/strong&gt; PostSharp licenses to two lucky attendees!&lt;/p&gt;  &lt;p&gt;So hurry up, sign up here: &lt;a href="https://www3.gotomeeting.com/register/724468246"&gt;https://www3.gotomeeting.com/register/724468246&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=jq-Jtzn9fOs:eP03CUA5-5E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=jq-Jtzn9fOs:eP03CUA5-5E:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=jq-Jtzn9fOs:eP03CUA5-5E:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=jq-Jtzn9fOs:eP03CUA5-5E:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=jq-Jtzn9fOs:eP03CUA5-5E:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=jq-Jtzn9fOs:eP03CUA5-5E:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=jq-Jtzn9fOs:eP03CUA5-5E:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=jq-Jtzn9fOs:eP03CUA5-5E:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=jq-Jtzn9fOs:eP03CUA5-5E:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=jq-Jtzn9fOs:eP03CUA5-5E:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=jq-Jtzn9fOs:eP03CUA5-5E:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=jq-Jtzn9fOs:eP03CUA5-5E:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/postsharp/~4/jq-Jtzn9fOs" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Igal Tabachnik</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/post.aspx?id=2b69a490-c30f-4864-ad36-fdfe9dfd861d</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.sharpcrafters.com/blog/trackback.axd?id=2b69a490-c30f-4864-ad36-fdfe9dfd861d</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/post/Live-Webinar-How-to-Stay-DRY-with-AOP-and-PostSharp.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/syndication.axd?post=2b69a490-c30f-4864-ad36-fdfe9dfd861d</wfw:commentRss><feedburner:origLink>http://www.sharpcrafters.com/blog/post.aspx?id=2b69a490-c30f-4864-ad36-fdfe9dfd861d</feedburner:origLink></item><item><title>Feature Focus: Showing message locations in the source code</title><link>http://feedproxy.google.com/~r/postsharp/~3/V74YW0WVWt8/post.aspx</link><category>Annoucement</category><category>Tutorial</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Igal Tabachnik</dc:creator><pubDate>Wed, 04 Jan 2012 08:13:00 PST</pubDate><guid isPermaLink="false">http://www.sharpcrafters.com/blog/post.aspx?id=51ad39f1-c320-4bac-80cc-0ea67adcbd15</guid><description>&lt;p&gt;During compilation, PostSharp takes great care in making sure that everything works correctly. When something goes wrong, PostSharp will report it as an error or a warning. Until now, however, whenever an error or a warning occurred, the developer had to manually navigate to that place in code.&lt;/p&gt;  &lt;p&gt;We are excited to announce that with &lt;a href="http://www.sharpcrafters.com/postsharp/download"&gt;PostSharp 2.1&lt;/a&gt; we’ve enhanced the errors and warnings with the exact location information, allowing you to simply double-click on the message and you’ll be taken to the error line!&lt;/p&gt;  &lt;p&gt;To enable this feature, go to &lt;strong&gt;Tools – Options – PostSharp&lt;/strong&gt;, and under &lt;strong&gt;Experimental&lt;/strong&gt;, set &lt;em&gt;&lt;strong&gt;Resolve Message Location&lt;/strong&gt;&lt;/em&gt; to &lt;strong&gt;True&lt;/strong&gt;:&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="" border="0" alt="" src="http://www.sharpcrafters.com/blog/image.axd?picture=12c004394b97e518.png" width="644" height="376" /&gt;&lt;/p&gt;  &lt;p&gt;Then, simply rebuild your solution, and if there are any warnings or errors, you’ll be able to see exactly where they are:&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="" border="0" alt="" src="http://www.sharpcrafters.com/blog/image.axd?picture=53d3d4df1ad21b74.png" width="644" height="481" /&gt;&lt;/p&gt;  &lt;p&gt;This is accomplished by specifying the member (in this case, the method) that is responsible for the message, in the aspect’s &lt;strong&gt;CompieTimeValidate&lt;/strong&gt; method:&lt;/p&gt;  &lt;pre&gt;// Validate the attribute usage.
public override bool CompileTimeValidate( MethodBase method )
{
    // Don't apply to constructors.
    if ( method is ConstructorInfo )
    {
        Message.Write( &lt;strong&gt;method&lt;/strong&gt;, SeverityType.Error, &amp;quot;CX0001&amp;quot;, 
                       &amp;quot;Cannot cache constructors.&amp;quot; );
        return false;
    }

    MethodInfo methodInfo = (MethodInfo) method;

    // Don't apply to void methods.
    if ( methodInfo.ReturnType.Name == &amp;quot;Void&amp;quot; )
    {
        Message.Write( &lt;strong&gt;method&lt;/strong&gt;, SeverityType.Error, &amp;quot;CX0002&amp;quot;, 
                       &amp;quot;Cannot cache void methods.&amp;quot; );
        return false;
    }

    // Does not support out parameters.
    ParameterInfo[] parameters = method.GetParameters();
    for ( int i = 0; i &amp;lt; parameters.Length; i++ )
    {
        if ( parameters[i].IsOut )
        {
            Message.Write( &lt;strong&gt;method&lt;/strong&gt;, SeverityType.Error, &amp;quot;CX0003&amp;quot;, 
                           &amp;quot;Cannot cache methods with return values.&amp;quot; );
            return false;
        }
    }

    return true;
}&lt;/pre&gt;

&lt;p&gt;Aspect developers are encouraged to include the member in error/warning messages. For more information, please refer to the documentation on &lt;a href="http://doc.sharpcrafters.com/postsharp-2.1/##PostSharp-2.1.chm/html/4390e8c1-6437-45ac-971b-b9efe7251572.htm"&gt;Working with Errors, Warnings and Messages&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Please note that this is not enabled by default as it is still experimental and might have an impact on performance. Please let us know how it works out for you!&lt;/p&gt;

&lt;p&gt;Happy PostSharping!&lt;/p&gt;

&lt;p&gt;-Igal&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=V74YW0WVWt8:ZFVU-Vmt77o:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=V74YW0WVWt8:ZFVU-Vmt77o:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=V74YW0WVWt8:ZFVU-Vmt77o:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=V74YW0WVWt8:ZFVU-Vmt77o:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=V74YW0WVWt8:ZFVU-Vmt77o:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=V74YW0WVWt8:ZFVU-Vmt77o:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=V74YW0WVWt8:ZFVU-Vmt77o:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=V74YW0WVWt8:ZFVU-Vmt77o:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=V74YW0WVWt8:ZFVU-Vmt77o:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=V74YW0WVWt8:ZFVU-Vmt77o:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=V74YW0WVWt8:ZFVU-Vmt77o:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=V74YW0WVWt8:ZFVU-Vmt77o:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/postsharp/~4/V74YW0WVWt8" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Igal Tabachnik</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/post.aspx?id=51ad39f1-c320-4bac-80cc-0ea67adcbd15</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.sharpcrafters.com/blog/trackback.axd?id=51ad39f1-c320-4bac-80cc-0ea67adcbd15</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/post/Feature-Focus-Showing-message-locations-in-the-source-code.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/syndication.axd?post=51ad39f1-c320-4bac-80cc-0ea67adcbd15</wfw:commentRss><feedburner:origLink>http://www.sharpcrafters.com/blog/post.aspx?id=51ad39f1-c320-4bac-80cc-0ea67adcbd15</feedburner:origLink></item><item><title>Feature Focus: View source code enhanced by PostSharp</title><link>http://feedproxy.google.com/~r/postsharp/~3/xRS4oHWsl9o/post.aspx</link><category>Tutorial</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Igal Tabachnik</dc:creator><pubDate>Wed, 21 Dec 2011 11:12:00 PST</pubDate><guid isPermaLink="false">http://www.sharpcrafters.com/blog/post.aspx?id=ea14d066-6761-4bb4-a620-8bca0a72fd47</guid><description>&lt;p&gt;As most of you know, PostSharp’s transformation (weaving) of aspects into your assemblies happens after the compilation. One of the most requested features is the ability to see the actual code that is produced by PostSharp. Until now, you had to manually open the newly compiled assembly in your favorite decompiler to see the produced code.&lt;/p&gt;  &lt;p&gt;We are delighted to announce that we’ve made viewing the source code in your favorite decompiler much easier – via a single click on the enhanced class or method:&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="" border="0" alt="" src="http://www.sharpcrafters.com/blog/image.axd?picture=6c44ed6f40b27715.png" width="644" height="434" /&gt;&lt;/p&gt;  &lt;p&gt;By clicking the &lt;strong&gt;See enhanced source code&lt;/strong&gt; link for the first time, you will be asked to select the decompiler you want to use (we currently support &lt;a href="http://www.jetbrains.com/decompiler/"&gt;dotPeek&lt;/a&gt;, &lt;a href="http://wiki.sharpdevelop.net/ILSpy.ashx"&gt;ILSpy&lt;/a&gt; and &lt;a href="http://www.reflector.net/"&gt;Reflector&lt;/a&gt;). You can always change the decompiler later from &lt;strong&gt;Tools – Options – PostSharp&lt;/strong&gt;:&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="" border="0" alt="" src="http://www.sharpcrafters.com/blog/image.axd?picture=19ce2c8f1e0157fb.png" width="644" height="376" /&gt;&lt;/p&gt;  &lt;p&gt;From now on, when you click on the &lt;strong&gt;See enhanced source code&lt;/strong&gt;, your chosen decompiler will open and show you exactly the source code, as it was modified by PostSharp!&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="" border="0" alt="" src="http://www.sharpcrafters.com/blog/image.axd?picture=2790987926438552.png" width="644" height="351" /&gt;&lt;/p&gt;  &lt;p&gt;This feature is available in the &lt;a href="http://www.sharpcrafters.com/downloads/postsharp-2.1/hot-fixes/v2.1.5.8-1748"&gt;latest version of PostSharp&lt;/a&gt;!&lt;/p&gt;  &lt;p&gt;Happy PostSharping!&lt;/p&gt;  &lt;p&gt;-Igal&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=xRS4oHWsl9o:fD4Si2kbovM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=xRS4oHWsl9o:fD4Si2kbovM:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=xRS4oHWsl9o:fD4Si2kbovM:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=xRS4oHWsl9o:fD4Si2kbovM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=xRS4oHWsl9o:fD4Si2kbovM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=xRS4oHWsl9o:fD4Si2kbovM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=xRS4oHWsl9o:fD4Si2kbovM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=xRS4oHWsl9o:fD4Si2kbovM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=xRS4oHWsl9o:fD4Si2kbovM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=xRS4oHWsl9o:fD4Si2kbovM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=xRS4oHWsl9o:fD4Si2kbovM:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=xRS4oHWsl9o:fD4Si2kbovM:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/postsharp/~4/xRS4oHWsl9o" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Igal Tabachnik</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/post.aspx?id=ea14d066-6761-4bb4-a620-8bca0a72fd47</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">1</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.sharpcrafters.com/blog/trackback.axd?id=ea14d066-6761-4bb4-a620-8bca0a72fd47</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/post/Feature-Focus-View-source-code-enhanced-by-PostSharp.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/syndication.axd?post=ea14d066-6761-4bb4-a620-8bca0a72fd47</wfw:commentRss><feedburner:origLink>http://www.sharpcrafters.com/blog/post.aspx?id=ea14d066-6761-4bb4-a620-8bca0a72fd47</feedburner:origLink></item><item><title>Free Course from Donald Belcham on Pluralsight</title><link>http://feedproxy.google.com/~r/postsharp/~3/6JWuMrm0CBI/post.aspx</link><category>Community</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Britt King</dc:creator><pubDate>Wed, 21 Dec 2011 06:08:00 PST</pubDate><guid isPermaLink="false">http://www.sharpcrafters.com/blog/post.aspx?id=69a609b1-159a-4688-a0a9-b051a3369149</guid><description>&lt;p&gt;&lt;img style="margin: 0px 5px 0px 0px; display: inline; float: left" alt="" align="left" src="http://d27zia7qovbru8.cloudfront.net/Design/images/contacts/0a4657a6-aef1-dd11-96e1-005056c00001-98293c4bf8649a68b0ea735479a7c47e.jpg" width="80" height="110" /&gt;&lt;/p&gt;  &lt;p&gt;If learning more about Aspect Oriented Programming is on your to-do list for 2012, we have some very good news for you.&lt;/p&gt;  &lt;p&gt;We’ve teamed up with the good folks at &lt;a href="http://www.pluralsight.com"&gt;Pluralsight&lt;/a&gt; to make it easier than ever for developers to get up to speed on developing with aspects. PostSharp users can sign-up to receive a free 30-day trial membership good towards one Pluralsight online course.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.sharpcrafters.com/postsharp/documentation/pluralsight"&gt;Start learning about Aspect Oriented Programming for .NET today &amp;gt;&amp;gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Pluralsight, “&lt;em&gt;the leader in high-quality online training for hardcore developers&lt;/em&gt;,” has a huge library of online courses to choose from but, naturally, the course we recommend is &lt;a href="http://www.pluralsight-training.net/microsoft/Courses/TableOfContents?courseName=aop"&gt;Aspect Oriented Programming for .NET&lt;/a&gt; by PostSharp MVP and Pluralsight Author, &lt;a href="http://www.sharpcrafters.com/community/profile?id=0a4657a6-aef1-dd11-96e1-005056c00001-3920a606"&gt;Donald Belcham&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Donald is a senior software developer, independent contractor, author, and trainer based in Edmonton, Canada. He spoke about the topic of Aspect Oriented Programming at NDC and DevTeach Montreal earlier this year, and published the online course on Pluralsight in June.&lt;/p&gt;  &lt;p&gt;The course is divided into four parts:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Introduction to AOP &lt;/li&gt;    &lt;li&gt;AOP using Interceptors &lt;/li&gt;    &lt;li&gt;AOP using IL Code Weaving &lt;/li&gt;    &lt;li&gt;AOP beyond decorators &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;From Donald: “&lt;em&gt;My course is perfect for developers who want to learn how to avoid code repetition by implementing AOP in .NET projects using IL Code Weaving frameworks like PostSharp, Interception frameworks like Castle Windsor, and even how to implement AOP without following the traditional decorator pattern&lt;/em&gt;.”&lt;/p&gt;  &lt;p&gt;Apply for your free 30-day Pluralsight trial membership today and, upon approval, we’ll email you a unique login code plus a link to a special sign-in page for PostSharp users.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.sharpcrafters.com/postsharp/documentation/pluralsight"&gt;Start your free 30-day trial membership today &amp;gt;&amp;gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;-Britt&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=6JWuMrm0CBI:v3JyuCjZutw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=6JWuMrm0CBI:v3JyuCjZutw:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=6JWuMrm0CBI:v3JyuCjZutw:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=6JWuMrm0CBI:v3JyuCjZutw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=6JWuMrm0CBI:v3JyuCjZutw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=6JWuMrm0CBI:v3JyuCjZutw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=6JWuMrm0CBI:v3JyuCjZutw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=6JWuMrm0CBI:v3JyuCjZutw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=6JWuMrm0CBI:v3JyuCjZutw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=6JWuMrm0CBI:v3JyuCjZutw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=6JWuMrm0CBI:v3JyuCjZutw:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=6JWuMrm0CBI:v3JyuCjZutw:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/postsharp/~4/6JWuMrm0CBI" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Britt King</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/post.aspx?id=69a609b1-159a-4688-a0a9-b051a3369149</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">1</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.sharpcrafters.com/blog/trackback.axd?id=69a609b1-159a-4688-a0a9-b051a3369149</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/post/Build-Aspects-Like-Donald-Belcham.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/syndication.axd?post=69a609b1-159a-4688-a0a9-b051a3369149</wfw:commentRss><feedburner:origLink>http://www.sharpcrafters.com/blog/post.aspx?id=69a609b1-159a-4688-a0a9-b051a3369149</feedburner:origLink></item><item><title>PostSharp Makes Hanselman's 2011 Ultimate Tools List</title><link>http://feedproxy.google.com/~r/postsharp/~3/j_k0L8FDzxs/post.aspx</link><category>Annoucements</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Britt King</dc:creator><pubDate>Fri, 02 Dec 2011 05:33:00 PST</pubDate><guid isPermaLink="false">http://www.sharpcrafters.com/blog/post.aspx?id=ec30966f-8469-455e-8c86-0403ea882ae7</guid><description>&lt;p&gt;&lt;img style="margin: 0px 5px 5px 0px; display: inline; float: left" align="left" src="https://lh3.googleusercontent.com/-73Eb7tLaAEM/AAAAAAAAAAI/AAAAAAAAAAA/IVw0N5Ls300/photo.jpg" width="131" height="131" /&gt;&lt;/p&gt;  &lt;p&gt;Scott Hanselman knows tools.&lt;/p&gt;  &lt;p&gt;As a Principle Program Manager at Microsoft, and one of the most sought-after developer speakers on the planet, Scott has his finger planted firmly on the pulse of the .NET community. Luckily for all of us, he only uses his powers for good by entertaining and educating the community about software development across a variety of channels including &lt;a href="http://hanselminutes.com/"&gt;podcasts&lt;/a&gt;, &lt;a href="http://www.hanselman.com/blog/CategoryView.aspx?category=Speaking"&gt;presentation and speaking tips&lt;/a&gt;, &lt;a href="http://www.amazon.com/gp/product/0470502207?ie=UTF8&amp;amp;ref_=sr_1_1&amp;amp;s=books&amp;amp;qid=1270496811&amp;amp;sr=1-1&amp;amp;linkCode=shr&amp;amp;camp=213733&amp;amp;creative=393185&amp;amp;tag=diabeticbooks"&gt;books&lt;/a&gt;, and more.&lt;/p&gt;  &lt;p&gt;Since his first ultimate tools list in 2003, the popularity and length of Scott’s annual lists have grown considerably. This year’s list includes categories such as “The Big Ten Life and Work-Changing Utilities,” “Rocking Sweet Windows 7 Specific Stuff,” and “A (.NET) Developer's Life,” to name a few.&lt;/p&gt;  &lt;p&gt;We’re thrilled and honored to see &lt;a href="http://hanselman.com/tools"&gt;PostSharp included in Scott’s 2011 ultimate tools list&lt;/a&gt; alongside so many other great tools. We know we wouldn’t have made the list without the help of our &lt;a href="http://www.sharpcrafters.com/customers"&gt;customers&lt;/a&gt;, &lt;a href="http://www.sharpcrafters.com/community"&gt;MVPs&lt;/a&gt;, and &lt;a href="http://www.sharpcrafters.com/training/partners"&gt;partners&lt;/a&gt;. Thank you, all.&lt;/p&gt;  &lt;p&gt;The ultimate tools list wasn’t our first run-in with Scott in 2011. Gael sat down with him in September as part of his startup podcast series, to discuss the challenges of taking &lt;a href="http://hanselminutes.com/286/startup-series-postsharp-from-open-source-to-commercial-business-with-gael-fraiteur"&gt;PostSharp from open source to commercial business&lt;/a&gt;. The two talked about aspect-oriented programming and Scott rightly pointed out that AOP is another kind of abstraction, which is the whole point of what computers are supposed to do for us, work that’s not fun like logging and transactions. &lt;/p&gt;  &lt;p&gt;Since the beginning of 2011 we’ve focused on spreading the word about the benefits of aspect oriented programming for .NET with &lt;a href="http://www.sharpcrafters.com/training"&gt;in-office trainings&lt;/a&gt;, &lt;a href="http://www.sharpcrafters.com/community/events"&gt;user group and conference presentations&lt;/a&gt;, &lt;a href="http://www.dotnetrocks.com/default.aspx?showNum=672"&gt;podcasts&lt;/a&gt; and &lt;a href="http://www.sharpcrafters.com/postsharp/documentation/screencasts"&gt;screencasts&lt;/a&gt;, &lt;a href="http://www.sharpcrafters.com/postsharp/white-paper"&gt;white paper&lt;/a&gt; and &lt;a href="http://www.sharpcrafters.com/community/contributions"&gt;blog posts&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;It seems to be working. &lt;/p&gt;  &lt;p&gt;In September, the same month as the Hanselminutes podcast, we announced a rising trend in AOP adoption among developers in large organizations, especially those in the Fortune 500, and created case studies showing how two big companies, &lt;a href="http://www.sharpcrafters.com/customers/siemens"&gt;Siemens Audiology&lt;/a&gt; and &lt;a href="http://www.sharpcrafters.com/customers/thales"&gt;Thales Information Systems&lt;/a&gt;, are succeeding with PostSharp.&lt;/p&gt;  &lt;p&gt;There’s more to come in 2012, and we look forward to speaking with more of you about your experience with PostSharp. Special thanks goes out to Scott Hanselman for his seemingly tireless commitment to the community and his never-ending quest to find the ultimate tools for .NET.&lt;/p&gt;  &lt;p&gt;Happy PostSharping!&lt;/p&gt;  &lt;p&gt;-Britt&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=j_k0L8FDzxs:TYwDMGH9iWE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=j_k0L8FDzxs:TYwDMGH9iWE:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=j_k0L8FDzxs:TYwDMGH9iWE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=j_k0L8FDzxs:TYwDMGH9iWE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=j_k0L8FDzxs:TYwDMGH9iWE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=j_k0L8FDzxs:TYwDMGH9iWE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=j_k0L8FDzxs:TYwDMGH9iWE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=j_k0L8FDzxs:TYwDMGH9iWE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=j_k0L8FDzxs:TYwDMGH9iWE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=j_k0L8FDzxs:TYwDMGH9iWE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=j_k0L8FDzxs:TYwDMGH9iWE:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=j_k0L8FDzxs:TYwDMGH9iWE:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/postsharp/~4/j_k0L8FDzxs" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Britt King</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/post.aspx?id=ec30966f-8469-455e-8c86-0403ea882ae7</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.sharpcrafters.com/blog/trackback.axd?id=ec30966f-8469-455e-8c86-0403ea882ae7</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/post/Hanselmans-Ultimate-Tools-List.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/syndication.axd?post=ec30966f-8469-455e-8c86-0403ea882ae7</wfw:commentRss><feedburner:origLink>http://www.sharpcrafters.com/blog/post.aspx?id=ec30966f-8469-455e-8c86-0403ea882ae7</feedburner:origLink></item><item><title>IdeaBlade releases DevForce Code First</title><link>http://feedproxy.google.com/~r/postsharp/~3/HrrKxXCEwks/post.aspx</link><category>Annoucement</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Gael Fraiteur</dc:creator><pubDate>Mon, 07 Nov 2011 13:45:40 PST</pubDate><guid isPermaLink="false">http://www.sharpcrafters.com/blog/post.aspx?id=20d3f321-282a-4d3e-9fb2-45c0ea8939db</guid><description>&lt;p&gt;I’m thrilled to announce that our partner &lt;a href="http://www.ideablade.com/" target="_blank"&gt;IdeaBlade&lt;/a&gt; has just released a new version of &lt;a href="http://www.ideablade.com/solutions/solutions.aspx" target="_blank"&gt;DevForce&lt;/a&gt;. This application framework already provided pretty much all of the wiring you need to develop rich line-of-business applications (Silverlight and WPF backed by WCF, Entity Framework, OData). The last release now supports&amp;#160; &lt;a href="http://drc.ideablade.com/xwiki/bin/view/Documentation/code-first" target="_blank"&gt;domain models written for Entity Framework in Code First style&lt;/a&gt;… and that still respect the spirit of Code First: nice, clean code, free from infrastructure boilerplate.&lt;/p&gt;  &lt;p&gt;Guess who is writing that boilerplate for you? Right: PostSharp. What’s nice with DevForce is that you can start coding immediately and don’t have to understand anything about AOP and PostSharp since DevForce provides all the aspects you need. Even better: you don’t need to download PostSharp and you don’t have to check-out any license: all is included in the IdeaBlade package.&lt;/p&gt;  &lt;p&gt;See! I managed to avoid the c*c*c word.&lt;/p&gt;  &lt;p&gt;I’d like to thank Albert and his team for their efforts and feedback during the RC stage of PostSharp 2.1. I’m sure DevForce and PostSharp will benefit from each other and will make it even easier to develop strong LOB applications.&lt;/p&gt;  &lt;p&gt;Happy PostSharping – now even to those who never heard of PostSharp.&lt;/p&gt;  &lt;p&gt;-gael&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=HrrKxXCEwks:E73zfp-63Pw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=HrrKxXCEwks:E73zfp-63Pw:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=HrrKxXCEwks:E73zfp-63Pw:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=HrrKxXCEwks:E73zfp-63Pw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=HrrKxXCEwks:E73zfp-63Pw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=HrrKxXCEwks:E73zfp-63Pw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=HrrKxXCEwks:E73zfp-63Pw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=HrrKxXCEwks:E73zfp-63Pw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=HrrKxXCEwks:E73zfp-63Pw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=HrrKxXCEwks:E73zfp-63Pw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=HrrKxXCEwks:E73zfp-63Pw:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=HrrKxXCEwks:E73zfp-63Pw:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/postsharp/~4/HrrKxXCEwks" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Gael Fraiteur</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/post.aspx?id=20d3f321-282a-4d3e-9fb2-45c0ea8939db</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">1</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.sharpcrafters.com/blog/trackback.axd?id=20d3f321-282a-4d3e-9fb2-45c0ea8939db</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/post/IdeaBlade-releases-DevForce-Code-First.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/syndication.axd?post=20d3f321-282a-4d3e-9fb2-45c0ea8939db</wfw:commentRss><feedburner:origLink>http://www.sharpcrafters.com/blog/post.aspx?id=20d3f321-282a-4d3e-9fb2-45c0ea8939db</feedburner:origLink></item><item><title>Announcing PostSharp 2.1 RTM</title><link>http://feedproxy.google.com/~r/postsharp/~3/NyZQfWOvAbs/post.aspx</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/" /><pubDate>Mon, 31 Oct 2011 04:07:00 PDT</pubDate><guid isPermaLink="false">http://www.sharpcrafters.com/blog/post.aspx?id=cff90a1c-2f3e-403f-966e-2f8a96a58df4</guid><description>&lt;p&gt;I&amp;rsquo;m delighted to announce the release of PostSharp 2.1 RTM, available for download on &lt;a href="http://www.sharpcrafters.com/downloads/postsharp-2.1/rtm/PostSharp-2.1.5.1.exe"&gt;our web site&lt;/a&gt; and on &lt;a href="http://www.nuget.org/List/Packages/PostSharp"&gt;NuGet&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The last release candidate has been available as the front-page download for more than a month now with no reported bugs. PostSharp 2.1 becomes the recommended version for everyone and is now considered more stable than the 2.0 branch.&lt;/p&gt;
&lt;h2&gt;New features&lt;/h2&gt;
&lt;p&gt;PostSharp 2.1 brings the following improvements to PostSharp 2.0:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Improved build-time performance: up to 5x faster. &lt;a href="http://www.sharpcrafters.com/blog/2011/01/default.aspx"&gt;Read more.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Architecture validation: build-time validation of design rules. &lt;a href="http://www.sharpcrafters.com/blog/post/Architectural-Validation.aspx"&gt;Read more.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Extended reflection API: programmatically navigate code references. &lt;a href="http://www.sharpcrafters.com/blog/post/New-in-PostSharp-21-Reflecting-Custom-Attributes.aspx"&gt;Read more&lt;/a&gt; &lt;a href="http://www.sharpcrafters.com/blog/post/New-in-PostSharp-21-Navigating-Code-Relationships.aspx"&gt;and more&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;NuGet packaging and improved no-setup deployment experience. &lt;a href="http://www.sharpcrafters.com/blog/post/New-in-PostSharp-21-NuGet-Package.aspx"&gt;Read more.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Support for obfuscators: we now support Dotfuscator. &lt;a href="http://www.sharpcrafters.com/blog/post/Whate28099s-New-in-PostSharp-21-Support-for-Obfuscation-(Dotfuscator).aspx"&gt;Read more.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Improved Visual Studio Extension (PostSharp tab page in project properties).&lt;/li&gt;
&lt;li&gt;Warnings and errors now come with file/line information. The feature is optional and must be enabled manually from Visual Studio options. We&amp;rsquo;re eager to hear feedback about this feature from customers with larger projects. &lt;/li&gt;
&lt;li&gt;Support for Silverlight 5 and Windows Phone 7.1. &lt;/li&gt;
&lt;li&gt;Compatibility with Code Contracts 4. &lt;/li&gt;
&lt;li&gt;Improved messaging API. &lt;/li&gt;
&lt;li&gt;Streamlined licensing experience and &amp;ldquo;getting started&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;License server (optional).&lt;/li&gt;
&lt;li&gt;Streamlined &amp;ldquo;getting started&amp;rdquo; experience.&lt;/li&gt;
&lt;li&gt;Warnings can be disabled locally (for a specific element of code) using the &lt;strong&gt;IgnoreWarning&lt;/strong&gt; custom attribute. See &lt;a href="http://doc.sharpcrafters.com/postsharp-2.1/Content.aspx/PostSharp-2.1.chm/html/dbcf53d8-7525-48c2-b5fc-0aea945c6957.htm"&gt;online documentation&lt;/a&gt; for details. &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Bug fixes&lt;/h2&gt;
&lt;p&gt;The RTM fixes the following issues from RC2:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;"EnhancedByPostSharpAttribute" causes issues with the WPF compiler&lt;/li&gt;
&lt;li&gt;Aspected methods with parameter of generic types are not underlined in VS code editor&lt;/li&gt;
&lt;li&gt;Constant SkipPostSharp does not work&lt;/li&gt;
&lt;li&gt;Different versions of PostSharp cannot be used in the same solution&lt;/li&gt;
&lt;li&gt;Error due to file lock of *.vhost.exe&lt;/li&gt;
&lt;li&gt;Invalid version number is written in native resources&lt;/li&gt;
&lt;li&gt;MSBuild error "CodeContractsPerformCodeAnalysis target is missing" with Code Contracts Standard (without Code Analysis)&lt;/li&gt;
&lt;li&gt;Type parser throws exception with arrays or generic types&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Upgrading from PostSharp 2.0&lt;/h2&gt;
&lt;p&gt;This new version is fully backward compatible with PostSharp 2.0 (except one breaking bug fix), and can be installed side-by-side with PostSharp 2.0. In order to upgrade, you should just update the references to PostSharp.dll (and possibly to PostSharp.targets, if PostSharp is installed in source control). A utility contained in PostSharp HQ helps you converting projects from 2.0 to 2.1.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The upgrade is free for everyone&lt;/strong&gt; and your 2.0 license key will work with 2.1. However, you will be asked to enter your license key.&lt;/p&gt;
&lt;p&gt;Even if you are happy with the features of 2.0, &lt;strong&gt;you have to upgrade to 2.1 because your projects are going to compile damn faster&lt;/strong&gt;! Frankly. PostSharp has now the fastest MSIL engine on the market.&lt;/p&gt;
&lt;h2&gt;Announcing PostSharp 2.0 Update 6&lt;/h2&gt;
&lt;p&gt;By the way, we&amp;rsquo;ve also updated the PostSharp 2.0 release. It contains the following fixes compared to the previous update. Needless to say, these fixes are also included in the 2.1 release.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Aspect instance fields should not be marked as serializable&lt;/li&gt;
&lt;li&gt;Aspects may conflict with themselves&lt;/li&gt;
&lt;li&gt;Attempt to use two adornment layers when symbol file is updated&lt;/li&gt;
&lt;li&gt;BaseMarkerManager.RefreshTextMarkers causes AccessViolationException&lt;/li&gt;
&lt;li&gt;Collapsed region names should not be underlined by the VSX&lt;/li&gt;
&lt;li&gt;CSharpLanguageAdapter.VisitPropertyAccessor causes CodeProperty.get_Parent to throw InvalidOperationException&lt;/li&gt;
&lt;li&gt;Exception in MulticastAtributeTask when a parameter-level MulticastAttribute is applied to a property&lt;/li&gt;
&lt;li&gt;Exception in MulticastAttributeTask with inheritance on generic methods&lt;/li&gt;
&lt;li&gt;Exception when an aspect is applied to a generic protected method, or a protected method of a generic type, in a third assembly.&lt;/li&gt;
&lt;li&gt;Exception when an aspect is applied to a virtual method of a sealed/value type&lt;/li&gt;
&lt;li&gt;Exception with multicasting inheritance on generic methods.&lt;/li&gt;
&lt;li&gt;ImportMember throws an exception when a member is a property and an accessor is missing.&lt;/li&gt;
&lt;li&gt;In IntroduceMember, CopyCustomAttribute with merge does not work&lt;/li&gt;
&lt;li&gt;Incompatibility of the PostSharp VSX with CodeRush - collapsed regions&lt;/li&gt;
&lt;li&gt;Invalid code generation when several OnMethodBoundary aspects are applied&lt;/li&gt;
&lt;li&gt;Invalid code generation with a MSIL-serialized aspect containing an array argument&lt;/li&gt;
&lt;li&gt;Invalid handling of generic instances in reflection wrappers&lt;/li&gt;
&lt;li&gt;Invalid MSIL generation when [IntroduceMember] is applied to a member with a generic type argument&lt;/li&gt;
&lt;li&gt;InvalidCastException when IAspectProvider is used when MsilAspectSerializer, and a non-instrinsic is passed to the ObjectConstruction&lt;/li&gt;
&lt;li&gt;InvalidComObjectException from SolutionWatcher constructor&lt;/li&gt;
&lt;li&gt;ManagedDotNet40Platform.GetGetClrIdentityManagerProc throws COMException: The handle is invalid.&lt;/li&gt;
&lt;li&gt;Many features MethodRefDeclaration fail when the method refers to an implicit method of multidimensional arrays&lt;/li&gt;
&lt;li&gt;Method-level MulticastAttributes with multicast inheritance are not multicast to derived types accross assemblies&lt;/li&gt;
&lt;li&gt;MSBuild step "PostSharp20CopyOutputToCodeAnalysis" can fail because of file locking&lt;/li&gt;
&lt;li&gt;Multicast attributes are applied to anonymous methods, but should not&lt;/li&gt;
&lt;li&gt;MulticastAttribute.TargetMemberAttributes is not respected for properties and events&lt;/li&gt;
&lt;li&gt;NullReferenceException in QuickInfoTracker.OnMouseMove&lt;/li&gt;
&lt;li&gt;ProjectWatcher.UpdateSymbolPath throws NullReferenceException&lt;/li&gt;
&lt;li&gt;Some debugging sequence points are dropped&lt;/li&gt;
&lt;li&gt;ToolInvocationHelper.InvokeTool process output listener causes ArgumentOutOfRangeException on&lt;/li&gt;
&lt;li&gt;UpdateCheckUtility.BeginRetrieveMessages throws ThreadStartException&lt;/li&gt;
&lt;li&gt;UpdateCheckUtility.BeginRetrieveMessages throws ThreadStartException&lt;/li&gt;
&lt;li&gt;VsPackage.BeginInvoke throws COMException&lt;/li&gt;
&lt;li&gt;Win32Exception in PostSharp.VisualStudio.HWndDispatcher.BeginInvoke&lt;/li&gt;
&lt;li&gt;Windows Phone 7 does not support tail calls generated by PostSharp&lt;/li&gt;
&lt;li&gt;WriteWeavingSymbolsTask.Execute throws UnauthorizedAccessException&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;What&amp;rsquo;s Next?&lt;/h2&gt;
&lt;p&gt;It has been precisely one year since I started working on PostSharp 2.1. Arguably, it took way too much time to get that release out of the door. And here&amp;rsquo;s why: most of our time was invested in building the company and spreading the work about AOP. Since July, I&amp;rsquo;ve started research and planning for the next major version of PostSharp and a new product code-named Resonance, which will be to .NET software what magnetic resonance is to human body (detailed and non-invasive imaging). We&amp;rsquo;ve hired two software developers and, while PostSharp 2.1 was maturing, we started real development on the new &amp;ldquo;thing&amp;rdquo;. You&amp;rsquo;re going to be amazed, I promise.&lt;/p&gt;
&lt;p&gt;But today, we&amp;rsquo;ve become confident that PostSharp 2.1 is ready for production, and it&amp;rsquo;s a great time for you to upgrade.&lt;/p&gt;
&lt;p&gt;Happy PostSharping!&lt;/p&gt;
&lt;p&gt;-gael&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=NyZQfWOvAbs:qFX-7gtDb0o:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=NyZQfWOvAbs:qFX-7gtDb0o:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=NyZQfWOvAbs:qFX-7gtDb0o:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=NyZQfWOvAbs:qFX-7gtDb0o:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=NyZQfWOvAbs:qFX-7gtDb0o:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=NyZQfWOvAbs:qFX-7gtDb0o:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=NyZQfWOvAbs:qFX-7gtDb0o:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=NyZQfWOvAbs:qFX-7gtDb0o:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=NyZQfWOvAbs:qFX-7gtDb0o:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=NyZQfWOvAbs:qFX-7gtDb0o:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=NyZQfWOvAbs:qFX-7gtDb0o:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=NyZQfWOvAbs:qFX-7gtDb0o:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/postsharp/~4/NyZQfWOvAbs" height="1" width="1"/&gt;</description><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/post.aspx?id=cff90a1c-2f3e-403f-966e-2f8a96a58df4</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">1</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.sharpcrafters.com/blog/trackback.axd?id=cff90a1c-2f3e-403f-966e-2f8a96a58df4</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/post/Announcing-PostSharp-21-RTM.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/syndication.axd?post=cff90a1c-2f3e-403f-966e-2f8a96a58df4</wfw:commentRss><feedburner:origLink>http://www.sharpcrafters.com/blog/post.aspx?id=cff90a1c-2f3e-403f-966e-2f8a96a58df4</feedburner:origLink></item><item><title>Announcing: PostSharp Training</title><link>http://feedproxy.google.com/~r/postsharp/~3/SGFCQ47yStQ/post.aspx</link><category>Annoucement</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Britt King</dc:creator><pubDate>Thu, 29 Sep 2011 05:26:00 PDT</pubDate><guid isPermaLink="false">http://www.sharpcrafters.com/blog/post.aspx?id=ac87621e-b7db-423b-9489-ce4d132ed2c5</guid><description>&lt;p&gt;We&amp;rsquo;re thrilled to finally announce the availability of PostSharp training, worldwide. We&amp;rsquo;ve assembled an experienced team of trainers and consultants to offer a comprehensive 2 day course that&amp;rsquo;s designed to bring you up to speed fast on aspect-oriented programming and PostSharp.&lt;/p&gt;
&lt;p&gt;The course includes hands-on labs and discussion where you&amp;rsquo;ll learn how to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;create PostSharp aspects; and&lt;/li&gt;
&lt;li&gt;successfully introduce PostSharp aspects into complex projects. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Upon completion, you&amp;rsquo;ll be able to apply what you&amp;rsquo;ve learned to your own applications, and produce cleaner, more efficient, higher quality code than ever before.&lt;/p&gt;
&lt;h2&gt;Meet our Training &amp;amp; Consulting Partners&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;img style="margin: 5px 5px 0px 20px; display: inline; float: right" src="http://d27zia7qovbru8.cloudfront.net/Design/images/Donald_Belcham-7df04d4eaf690fef57b3fab3478dd026.jpg" alt="" width="90" height="124" align="left" /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.igloocoder.com"&gt;Donald Belcham&lt;/a&gt; is a senior software developer, independent contractor, and agile development expert who is a strong supporter of fundamental OO patterns and practices. He is co-author of the book, Brownfield Application Development in .NET (Manning Press, 2008), and actively shares his expertise with other technical professionals at user groups, code camps and conferences held throughout the world. Past lectures have covered topics that encompass development practices, quality team leadership, and the intricacies of new and emerging technologies.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img style="margin: 5px 5px 0px 20px; display: inline; float: right" src="http://d27zia7qovbru8.cloudfront.net/Design/images/Golo_Roden-10352ac4a812298bc84781a73d07ee5f.jpg" alt="" width="91" height="130" align="left" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.des-eisbaeren-blog.de/"&gt;Golo Roden&lt;/a&gt;&lt;strong&gt; &lt;/strong&gt;works as self-employed trainer and consultant for C#, JavaScript and web development &amp;ndash; focusing on code quality and agile methods. In 2011 he launched the Agile Development Framework, a comprehensive approach which combines the successful elements of previous agile methods. He has written more than 100 articles for professional magazines, has given more than 50 talks at international conferences, and wrote a book on C# in 2008. Golo blogs regularly and writes a recurring column on C# specialties for dotnetpro magazine.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;img style="margin: 4px 5px 20px 20px; display: inline; float: right" src="http://d27zia7qovbru8.cloudfront.net/Design/images/endjin-logo-transparent-b212f406386f19260bd63da010387257.jpg" alt="" width="147" height="72" align="left" /&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://endjin.com/people"&gt;Endjin&lt;/a&gt; is a collaboration of like-minded people who are imbued with an infectious enthusiasm for solving business problems through the smart application of technology. Their endjin-eers are outstanding individuals who have come together from across the business, creative and technology community having demonstrated a mastery of their craft. Unconstrained by industry vertical, company size or budget; endjin is motivated by solving problems. Their goal is to energize your business whether it is through a 2 hour conversation or 2 years of team effort.&lt;/p&gt;
&lt;h2&gt;PostSharp Training Agenda&lt;/h2&gt;
&lt;p&gt;The standard public agenda is composed of the following modules (note: for private training other topics can be introduced after discussion with the trainer):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Introduction to AOP &lt;/li&gt;
&lt;li&gt;Basic aspects &lt;/li&gt;
&lt;li&gt;Applying aspects to code &lt;/li&gt;
&lt;li&gt;Interception aspects &lt;/li&gt;
&lt;li&gt;Aspect composition &lt;/li&gt;
&lt;li&gt;Composite aspects &lt;/li&gt;
&lt;li&gt;Deployment and build process integration &lt;/li&gt;
&lt;li&gt;Targeting different platforms &lt;/li&gt;
&lt;li&gt;Best practices &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We&amp;rsquo;ve got more exciting training news coming in the weeks ahead and, &lt;a href="http://www.sharpcrafters.com/training"&gt;if you sign-up now to request more information about PostSharp training&lt;/a&gt;, we&amp;rsquo;ll let you in on the exciting news (including an exclusive offer) before we announce it publicly.&lt;/p&gt;
&lt;p&gt;Happy PostSharping!&lt;/p&gt;
&lt;p&gt;-Britt&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=SGFCQ47yStQ:eZdYfwHtdkg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=SGFCQ47yStQ:eZdYfwHtdkg:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=SGFCQ47yStQ:eZdYfwHtdkg:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=SGFCQ47yStQ:eZdYfwHtdkg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=SGFCQ47yStQ:eZdYfwHtdkg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=SGFCQ47yStQ:eZdYfwHtdkg:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=SGFCQ47yStQ:eZdYfwHtdkg:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=SGFCQ47yStQ:eZdYfwHtdkg:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=SGFCQ47yStQ:eZdYfwHtdkg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=SGFCQ47yStQ:eZdYfwHtdkg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=SGFCQ47yStQ:eZdYfwHtdkg:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=SGFCQ47yStQ:eZdYfwHtdkg:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/postsharp/~4/SGFCQ47yStQ" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Britt King</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/post.aspx?id=ac87621e-b7db-423b-9489-ce4d132ed2c5</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">1</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.sharpcrafters.com/blog/trackback.axd?id=ac87621e-b7db-423b-9489-ce4d132ed2c5</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/post/Announcing-PostSharp-Training.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/syndication.axd?post=ac87621e-b7db-423b-9489-ce4d132ed2c5</wfw:commentRss><feedburner:origLink>http://www.sharpcrafters.com/blog/post.aspx?id=ac87621e-b7db-423b-9489-ce4d132ed2c5</feedburner:origLink></item><item><title>Announcing PostSharp 2.1 RC 2</title><link>http://feedproxy.google.com/~r/postsharp/~3/TJZTKc4EmP0/post.aspx</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Gael Fraiteur</dc:creator><pubDate>Wed, 21 Sep 2011 02:21:37 PDT</pubDate><guid isPermaLink="false">http://www.sharpcrafters.com/blog/post.aspx?id=4e1261b7-fc2f-4ec8-b2a1-0b9616c6b4f6</guid><description>&lt;p&gt;I’m pleased to announce the second release candidate of PostSharp 2.1, available for download today on our &lt;a href="http://www.sharpcrafters.com/postsharp/download" target="_blank"&gt;web site&lt;/a&gt; and on &lt;a href="http://www.nuget.org/List/Packages/PostSharp" target="_blank"&gt;NuGet&lt;/a&gt;. The first RC proved to be very stable, so this new version contains only relatively minor bug fixes. This RC also contains all bug fixes from the 2.0 branch. &lt;/p&gt;  &lt;p&gt;Here’s the list of bugs that have been fixed in this release:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;CopyCustomAttributes causes exception when several types are passed to the constructor&lt;/li&gt;    &lt;li&gt;Fields are not visible by the debugger when a class has been moved to a binding class&lt;/li&gt;    &lt;li&gt;ImageWriter sets the section virtual size to an invalid value, causing failure in Windows Phone&lt;/li&gt;    &lt;li&gt;Invalid code generation when introducing a property or event of an open generic type&lt;/li&gt;    &lt;li&gt;Invalid code generation when introducing a property with a private property setter&lt;/li&gt;    &lt;li&gt;MainForm.CloseNotificationIcon throws InvalidOperationException after hibernation&lt;/li&gt;    &lt;li&gt;MSBuild failure when building a project on a FAT system (hard links not supported)&lt;/li&gt;    &lt;li&gt;PostSharp HQ throws exception when saving a license key for all users&lt;/li&gt;    &lt;li&gt;Setup program displays maintenance dialog when in silent mode&lt;/li&gt;    &lt;li&gt;Setup program prompts to uninstall previous version of the VS extension even in silent mode&lt;/li&gt;    &lt;li&gt;The license registration wizard should not be displayed after a silent installation.&lt;/li&gt;    &lt;li&gt;Exception in MulticastAtributeTask when a parameter-level MulticastAttribute is applied to a property&lt;/li&gt;    &lt;li&gt;Unused AssemblyRefs are included in the final assembly&lt;/li&gt;    &lt;li&gt;MulticastAttribute.TargetMemberAttributes is not respected for properties and events&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;PostSharp 2.1 is the fastest and most stable version of PostSharp and the upgrade is recommended for any one. To convert your projects, either use NuGet, either open PostSharp HQ and click on &lt;em&gt;convert projects&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;We’re now planning for PostSharp 3 and a new, truly disruptive, product that will change the landscape of instrumentation and diagnostic of in-production applications. &lt;a href="http://www.sharpcrafters.com/company/jobs" target="_blank"&gt;We are hiring&lt;/a&gt;; drop us an email if you’re interested in joining the team.&lt;/p&gt;  &lt;p&gt;Happy PostSharping!&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;-gael&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=TJZTKc4EmP0:IjxruFAnSjU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=TJZTKc4EmP0:IjxruFAnSjU:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=TJZTKc4EmP0:IjxruFAnSjU:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=TJZTKc4EmP0:IjxruFAnSjU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=TJZTKc4EmP0:IjxruFAnSjU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=TJZTKc4EmP0:IjxruFAnSjU:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=TJZTKc4EmP0:IjxruFAnSjU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=TJZTKc4EmP0:IjxruFAnSjU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=TJZTKc4EmP0:IjxruFAnSjU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=TJZTKc4EmP0:IjxruFAnSjU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=TJZTKc4EmP0:IjxruFAnSjU:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=TJZTKc4EmP0:IjxruFAnSjU:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/postsharp/~4/TJZTKc4EmP0" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Gael Fraiteur</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/post.aspx?id=4e1261b7-fc2f-4ec8-b2a1-0b9616c6b4f6</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">2</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.sharpcrafters.com/blog/trackback.axd?id=4e1261b7-fc2f-4ec8-b2a1-0b9616c6b4f6</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/post/Announcing-PostSharp-21-RC-2.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/syndication.axd?post=4e1261b7-fc2f-4ec8-b2a1-0b9616c6b4f6</wfw:commentRss><feedburner:origLink>http://www.sharpcrafters.com/blog/post.aspx?id=4e1261b7-fc2f-4ec8-b2a1-0b9616c6b4f6</feedburner:origLink></item><item><title>PostSharp SDK is undocumented and unsupported</title><link>http://feedproxy.google.com/~r/postsharp/~3/pH3M53SHUWs/post.aspx</link><category>Community</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Gael Fraiteur</dc:creator><pubDate>Tue, 20 Sep 2011 02:24:00 PDT</pubDate><guid isPermaLink="false">http://www.sharpcrafters.com/blog/post.aspx?id=affb19ed-93fa-4954-8442-5413406c4ab8</guid><description>&lt;p&gt;This is one of these unpopular but necessary decisions that every software publisher has to do now and then. It’s &lt;a href="http://blogs.msdn.com/b/agile/archive/2011/04/08/on-deprecation.aspx" target="_blank"&gt;generally accepted&lt;/a&gt; that pulling off expensive but little-used features is a healthy decision because it frees resources that can be spent on more popular features. This is what we are doing with documentation and support of PostSharp SDK.&lt;/p&gt;  &lt;h2&gt;What is PostSharp SDK?&lt;/h2&gt;  &lt;p&gt;PostSharp is made of two principal components: &lt;em&gt;PostSharp.dll&lt;/em&gt; and &lt;em&gt;PostSharp.Sdk.dll.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;em&gt;PostSharp.dll&lt;/em&gt; is the high-level public API. It mostly contains interface definitions, abstract classes and custom attributes from which developers can derive their own aspects. This library is designed to be used by developers of business applications. It offers transformation primitives (such as: intercepting a method, wrapping a method, introducing an interface) that developers can add to their code.&amp;#160; &lt;em&gt;PostSharp.dll&lt;/em&gt; leverages real aspect-oriented programming, a disciplined extension of object-oriented programming. Just as a normal compiler, the high-level API enforces syntactic rules, and you will get a reasonable error message if you violate them.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;PostSharp.Sdk.dll&lt;/em&gt; is the opposite of &lt;em&gt;PostSharp.dll&lt;/em&gt;. Its public API allows you to modify .NET assemblies at a very low level. You can do everything. The API does not enforce any programming discipline or syntactic rules. You can create invalid assemblies without even getting a warning. It requires you to learn the MSIL specification and to understand most of the 565 pages of the &lt;a href="http://www.ecma-international.org/publications/standards/Ecma-335.htm" target="_blank"&gt;ECMA-335 specification&lt;/a&gt;. &lt;em&gt;PostSharp.Sdk.dll&lt;/em&gt; is made of several components. The most low-level ones (code model, image reader, image writer) are also found in Mono Cecil and Microsoft CCI, although PostSharp SDK has its own implementation. PostSharp SDK also includes several middle-level components such as the project loader, the aspect infrastructure (which could allow you to use PostSharp SDK to develop an aspect weaver that has different syntax than &lt;em&gt;PostSharp.dll&lt;/em&gt;), the aspect weaver (the implementation of the &lt;em&gt;PostSharp.dll&lt;/em&gt;), the custom attribute multitasking components, and much more.&lt;/p&gt;  &lt;h2&gt;PostSharp SDK is more complex than you think&lt;/h2&gt;  &lt;p&gt;Contrarily to PostSharp itself, PostSharp SDK has a very steep, but misleading, learning curve. You get quite quickly the illusion that you “got” it, but the devil is in details. The 80-20 rules does not apply to PostSharp SDK: what applies is 95-5: 95% of time is spent in addressing 5% of cases. Think of MSIL programming as hiking in high mountains without a map. You always have the illusion that the top is near, but whenever you climb on what appeared to be top, you discover another, higher top. If you want to have an idea of the effort you’ll need to reach the goal, you need a map; ECMA-335 and the PostSharp SDK class reference will give you a fair overview of the complexity of your task.&lt;/p&gt;  &lt;p&gt;So why do we have PostSharp SDK? First, for our own needs. From our own point of view, PostSharp SDK is the most important component of PostSharp. Secondly, because this API is useful to a tiny minority of ISVs with very specific needs (for instance: high focus on speed). They can afford to maintain MSIL skills because the effort is leveraged to thousands of customers. Third, because PostSharp SDK can be used to overcome missing features of &lt;em&gt;PostSharp.dll&lt;/em&gt;. But this is where things can go wrong.&lt;/p&gt;  &lt;h2&gt;PostSharp SDK is undocumented and unsupported&lt;/h2&gt;  &lt;p&gt;There has been some criticism that PostSharp SDK is undocumented. This is not accurate: the class reference is quite complete and contains more than what’s obvious from the method signature. Many actually claim that PostSharp SDK has the best documentation of all MSIL rewriting tools.&lt;/p&gt;  &lt;p&gt;What is true is there is no conceptual documentation. Let me be clear: the lack of conceptual of documentation is a &lt;em&gt;feature&lt;/em&gt;, not a defect. The SDK will not be better documented. As any company, we have to allocate limited resources to a potentially unlimited number of features. It does not economically make sense to spend time in documenting a very complex API that is used by a dozen of customers.&lt;/p&gt;  &lt;p&gt;The same holds for support. We cannot provide support on a highly complex and incompletely documented API. We cannot guide you through baby steps. PostSharp SDK is not supported. You use it at your own risks.&lt;/p&gt;  &lt;h2&gt;Nostra Culpa&lt;/h2&gt;  &lt;p&gt;On the support forum, you could often read answers that sounded like “this is not possible to do with &lt;em&gt;PostSharp.dll&lt;/em&gt; but can be done with &lt;em&gt;PostSharp.Sdk.dll&lt;/em&gt;”, followed by a disclaimer that PostSharp SDK is hard and you should maybe not try. This had led some customers to ask for more information for these specific cases, which I published on the blog. Mistake! These blog posts have been interpreted as an advertisement of and an invitation to use PostSharp SDK. I apologize for that. I will not advertise PostSharp SDK again. It will remain unsupported and undocumented. The harmful blog posts have been withdrawn.&lt;/p&gt;  &lt;h2&gt;PostSharp SDK still available&lt;/h2&gt;  &lt;p&gt;That said, PostSharp SDK is still available for use in the Professional Edition. We are only making it clearer that this feature is not officially supported, and must be used at own risk. I believe that it’s not a good idea to code directly MSIL instructions unless you can leverage the effort to thousands of customers (as we do), but you’re free to try. It’s just that you’re on your own.&lt;/p&gt;  &lt;p&gt;I’m aware this decision will be unpopular, but I’m convinced it’s a necessary one to continue provide good support to the community.&lt;/p&gt;  &lt;p&gt;Happy PostSharping !&lt;/p&gt;  &lt;p&gt;-gael&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=pH3M53SHUWs:hE3VsLTU2L4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=pH3M53SHUWs:hE3VsLTU2L4:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=pH3M53SHUWs:hE3VsLTU2L4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=pH3M53SHUWs:hE3VsLTU2L4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=pH3M53SHUWs:hE3VsLTU2L4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=pH3M53SHUWs:hE3VsLTU2L4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=pH3M53SHUWs:hE3VsLTU2L4:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=pH3M53SHUWs:hE3VsLTU2L4:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=pH3M53SHUWs:hE3VsLTU2L4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=pH3M53SHUWs:hE3VsLTU2L4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=pH3M53SHUWs:hE3VsLTU2L4:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=pH3M53SHUWs:hE3VsLTU2L4:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/postsharp/~4/pH3M53SHUWs" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Gael Fraiteur</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/post.aspx?id=affb19ed-93fa-4954-8442-5413406c4ab8</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">5</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.sharpcrafters.com/blog/trackback.axd?id=affb19ed-93fa-4954-8442-5413406c4ab8</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/post/PostSharp-SDK-is-undocumented-and-unsupported.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/syndication.axd?post=affb19ed-93fa-4954-8442-5413406c4ab8</wfw:commentRss><feedburner:origLink>http://www.sharpcrafters.com/blog/post.aspx?id=affb19ed-93fa-4954-8442-5413406c4ab8</feedburner:origLink></item><item><title>Announcing PostSharp 2.1 RC 1</title><link>http://feedproxy.google.com/~r/postsharp/~3/qPQ4BkIv1h4/post.aspx</link><category>Annoucement</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Gael Fraiteur</dc:creator><pubDate>Tue, 30 Aug 2011 07:41:02 PDT</pubDate><guid isPermaLink="false">http://www.sharpcrafters.com/blog/post.aspx?id=1ccfa95e-543e-4c82-82b2-4a0b05e54708</guid><description>&lt;p&gt;I’m excited to announce the first release candidate of PostSharp 2.1, available for download from &lt;a href="http://www.sharpcrafters.com/downloads/postsharp-2.1/rc-1/PostSharp-2.1.3.3.exe"&gt;our website&lt;/a&gt; and from the &lt;a href="http://www.nuget.org/List/Packages/PostSharp"&gt;NuGet official repository&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;PostSharp 2.1 is a minor upgrade of PostSharp 2.0; the upgrade is free for everybody. The objective of this version is to fix several gray spots in the previous release.&lt;/p&gt;  &lt;p&gt;This release candidate is ought to be of very high quality and free of known bugs, but needs to be tested by the community before it can be labeled stable. As required by the RC quality label, the &lt;a href="http://doc.sharpcrafters.com/postsharp-2.1/"&gt;online documentation&lt;/a&gt; has been updated to reflect the latest API.&lt;/p&gt;  &lt;p&gt;PostSharp 2.1 has full backward binary compatibility with PostSharp 2.0.&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;What’s new in RC 1?&lt;/h2&gt;  &lt;p&gt;This release candidates contains the following additions to the previous CTP:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The design of architecture validation (PostSharp.Constraints) has been finalized.&lt;/li&gt;    &lt;li&gt;Warnings can be disabled locally (for a specific element of code) using the &lt;strong&gt;IgnoreWarning&lt;/strong&gt; custom attribute. See &lt;a href="http://doc.sharpcrafters.com/postsharp-2.1/Content.aspx/PostSharp-2.1.chm/html/dbcf53d8-7525-48c2-b5fc-0aea945c6957.htm"&gt;online documentation&lt;/a&gt; for details.&lt;/li&gt;    &lt;li&gt;The PostSharp project property page in Visual Studio now allows you to specify which warnings should be globally ignored or escalated into errors.&lt;/li&gt;    &lt;li&gt;Compatibility with Code Contracts 4.0&lt;/li&gt;    &lt;li&gt;As an experimental feature, warnings and errors now come with file/line information. The feature must be enabled manually from Visual Studio options. We’re eager to hear feedback about this feature from customers with larger projects.&lt;/li&gt;    &lt;li&gt;17 bug fixes&lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;What’s new in PostSharp 2.1?&lt;/h2&gt;  &lt;p&gt;If you missed the previous announcements, here’s a list of new features in PostSharp 2.1 compared to version 2.0:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Improved build-time performance: up to 5x faster. &lt;a href="http://www.sharpcrafters.com/blog/2011/01/default.aspx"&gt;Read more.&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Architecture validation: build-time validation of design rules. &lt;a href="http://www.sharpcrafters.com/blog/post/Architectural-Validation.aspx"&gt;Read more.&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Extended reflection API: programmatically navigate code references. &lt;a href="http://www.sharpcrafters.com/blog/post/New-in-PostSharp-21-Reflecting-Custom-Attributes.aspx"&gt;Read more&lt;/a&gt; &lt;a href="http://www.sharpcrafters.com/blog/post/New-in-PostSharp-21-Navigating-Code-Relationships.aspx"&gt;and more&lt;/a&gt;.&lt;/li&gt;    &lt;li&gt;NuGet packaging and improved no-setup deployment experience. &lt;a href="http://www.sharpcrafters.com/blog/post/New-in-PostSharp-21-NuGet-Package.aspx"&gt;Read more.&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Support for obfuscators: we now support Dotfuscator. &lt;a href="http://www.sharpcrafters.com/blog/post/Whate28099s-New-in-PostSharp-21-Support-for-Obfuscation-(Dotfuscator).aspx"&gt;Read more.&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Support for Silverlight 5.&lt;/li&gt;    &lt;li&gt;Compatibility with Code Contracts 4.&lt;/li&gt;    &lt;li&gt;Improved messaging API.&lt;/li&gt;    &lt;li&gt;Tab page in Visual Studio project properties.&lt;/li&gt;    &lt;li&gt;Streamlined licensing experience.&lt;/li&gt;    &lt;li&gt;License server.&lt;/li&gt;    &lt;li&gt;Streamlined “getting started” experience.&lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;ul&gt;&lt;!--EndFragment--&gt;&lt;/ul&gt;  &lt;h2&gt;Upgrade your Projects&lt;/h2&gt;  &lt;p&gt;To upgrade your projects from PostSharp 2.0 to PostSharp 2.1 easily you can use the conversion utility included in the &lt;em&gt;PostSharp HQ&lt;/em&gt; application. Just open the app and click on “convert”, then select the folder containing your projects. References to libraries and MSBuild imports will be automatically fixed.&lt;/p&gt;  &lt;h2&gt;PostSharp 2.1 Roadmap&lt;/h2&gt;  &lt;p&gt;A release candidate means that we are confident in the code quality and is that all mandatory quality work, including documentation, has been done. PostSharp 2.1 is now the default version on our download page. We’ll wait a couple of weeks to allow the community to give this version a try, then publish the RTM or another RC, according to the feedback.&lt;/p&gt;  &lt;p&gt;Note that the license agreement allows for production use.&lt;/p&gt;  &lt;p&gt;It’s now time to &lt;a href="http://www.sharpcrafters.com/postsharp/download"&gt;download PostSharp 2.1&lt;/a&gt; and upgrade your projects!&lt;/p&gt;  &lt;p&gt;Happy PostSharping!&lt;/p&gt;  &lt;p&gt;-gael&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=qPQ4BkIv1h4:SHB0QUgXc5A:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=qPQ4BkIv1h4:SHB0QUgXc5A:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=qPQ4BkIv1h4:SHB0QUgXc5A:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=qPQ4BkIv1h4:SHB0QUgXc5A:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=qPQ4BkIv1h4:SHB0QUgXc5A:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=qPQ4BkIv1h4:SHB0QUgXc5A:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=qPQ4BkIv1h4:SHB0QUgXc5A:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=qPQ4BkIv1h4:SHB0QUgXc5A:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=qPQ4BkIv1h4:SHB0QUgXc5A:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=qPQ4BkIv1h4:SHB0QUgXc5A:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=qPQ4BkIv1h4:SHB0QUgXc5A:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=qPQ4BkIv1h4:SHB0QUgXc5A:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/postsharp/~4/qPQ4BkIv1h4" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Gael Fraiteur</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/post.aspx?id=1ccfa95e-543e-4c82-82b2-4a0b05e54708</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">1</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.sharpcrafters.com/blog/trackback.axd?id=1ccfa95e-543e-4c82-82b2-4a0b05e54708</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/post/Announcing-PostSharp-21-RC-1.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/syndication.axd?post=1ccfa95e-543e-4c82-82b2-4a0b05e54708</wfw:commentRss><feedburner:origLink>http://www.sharpcrafters.com/blog/post.aspx?id=1ccfa95e-543e-4c82-82b2-4a0b05e54708</feedburner:origLink></item><item><title>New in PostSharp 2.1: Architectural Validation</title><link>http://feedproxy.google.com/~r/postsharp/~3/SPbC-A1rUgg/post.aspx</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Matthew Groves</dc:creator><pubDate>Sat, 13 Aug 2011 12:57:00 PDT</pubDate><guid isPermaLink="false">http://www.sharpcrafters.com/blog/post.aspx?id=1d4a11da-1e25-4b14-9886-b74d1a3e263c</guid><description>&lt;p&gt;&lt;em&gt;The &lt;a href="http://www.sharpcrafters.com/blog/file.axd?file=7bf453be61b107b9.zip"&gt;full source code for this blog post&lt;/a&gt; is available for download&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;One of the most interesting features of PostSharp that sets it apart from other AOP tools is its ability to apply aspects at compile-time.  As I've explored in previous blog posts, this gives you the ability to do compile time checking and initialization, insteaad of costly and error prone runtime validation.  For instance, one could use CompileTimeValidate to enforce that a given aspect can only be used on MVC Controller methods.&lt;/p&gt;
&lt;pre&gt;    [Serializable]
    public class ConstrainedAspect : OnMethodBoundaryAspect
    {
        public override bool CompileTimeValidate(System.Reflection.MethodBase method)
        {
            if(!method.DeclaringType.IsSubclassOf(typeof(Controller)))
            {
                Message.Write(MessageLocation.Of(method),
				SeverityType.Error,
				"987",
				"Aspect can only be used on Controllers. " + 
				"You applied it on type {0}",
				method.DeclaringType.Name);
                return false;
            }
            return true;
        }

        public override void OnEntry(MethodExecutionArgs args)
        {
            var controller = (Controller) args.Instance;
            controller.ViewData["aspect"] =
			"Constrained Aspect was here at " + DateTime.Now;
        }
    }
&lt;/pre&gt;
&lt;p&gt;This nifty feature has led &lt;a href="http://davybrion.com/blog/2008/05/creating-sanity-checks/"&gt;some Postsharp users&lt;/a&gt; to create "aspects" that &lt;em&gt;only&lt;/em&gt; contain compile time validation.  An architect could put some code in here that helps to validate and enforce the architectural design: an "architectural unit test", if you will.  With PostSharp 2.1, these "constraints" become a first-class feature.&lt;/p&gt;
&lt;p&gt;There are two types of constraints available in PostSharp 2.1: scalar constraints and referential constraints.  The separation is partially a semantic one, as both types of constraints are just ways of enforcing rules at compile time that the C# compiler itself doesn't give you.  It's also a technical separation, as referential constraints are checked on all assemblies that reference the code element.  &lt;em&gt;(Note that you'll need to turn on architectural validation in the "PostSharp" tab of your project properties, and that this feature is available only in the &lt;a href="http://www.sharpcrafters.com/purchase/compare"&gt;professional version&lt;/a&gt;).&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Scalar Constraints&lt;/h3&gt;
&lt;p&gt;A scalar constraint is a simple constraint that is meant to affect a single piece of code in isolation.  This is the most like using a CompileTimeValidation method in an aspect, except without the aspect part.  For instance, if you are a user of NHibernate, you know that your entity classes must have virtual properties.  However, if you're like me, you might add a new property and forget to make it virtual.  Then, you compile your project, run it, go through a test case, and get a runtime error.  Wasted time!  Here's a scalar constraint that you can apply to your entities to make sure you don't forget.&lt;/p&gt;
&lt;pre&gt;    [Serializable]
    [MulticastAttributeUsage(MulticastTargets.Class)]
    public class NHEntityAttribute : MulticastAttribute, IScalarConstraint
    {
        public void ValidateCode(object target)
        {
            var targetType = (Type)target;
            var properties = targetType.GetProperties(
			BindingFlags.Public | BindingFlags.Instance);
            var virtualProperties = properties.Where(p =&amp;gt; !p.GetGetMethod().IsVirtual);
            foreach (var propertyInfo in virtualProperties)
            {
                Message.Write(MessageLocation.Of(targetType),
				SeverityType.Error,
				"998",
				"Property {0} in Entity class {1} is not virtual",
				propertyInfo.Name, targetType.FullName);
            }
        }

        public bool ValidateConstraint(object target)
        {
            return true;
        }
    }
&lt;/pre&gt;
&lt;p&gt;Note that ValidateConstraint exists to validate the application of the constraint itself (a validation of a validation!).  In my example above, I'm performing no validation at all and just returning true, but certainly you could check to make sure this validation is not applied to a static class, for instance.  If ValidateConstraint method returns false, then the constraint is considered not valid, and will not be applied.&lt;/p&gt;
&lt;p&gt;If you have all your entities in a single namespace, it's very easy to apply this constraint to all your entities (even ones that you haven't written yet) by multicasting that attribute. (For more info on multicasting, check out Dustin's excellent blog posts on multicasting: &lt;a href="http://www.sharpcrafters.com/blog/post/Day-2-Applying-Aspects-with-Multicasting-Part-1.aspx"&gt;part 1&lt;/a&gt; and &lt;a href="http://www.sharpcrafters.com/blog/post/Day-3-Applying-Aspects-with-Multicasting-Part-2.aspx"&gt;part 2&lt;/a&gt;).&lt;/p&gt;
&lt;pre&gt;[assembly: NHEntity(AttributeTargetTypes = "YourNamespace.Models.Entities")]
&lt;/pre&gt;
&lt;p&gt;When you forget the 'virtual' after you add a new property, you'll see something like this when you compile:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.sharpcrafters.com/blog/image.axd?picture=340c8beb01ed2fe4.png" alt="NHEntity compiler error" /&gt;&lt;/p&gt;
&lt;p&gt;You could use constraints like this for similar situations, like WCF DataMembers in a DataContract or OperatingContracts in a ServiceContract.  You can avoid a lot of frustration and wasted time.&lt;/p&gt;
&lt;h3&gt;Referential Constraints&lt;/h3&gt;
&lt;p&gt;Referential constraints are meant to enforce architectural design across assemblies, references, and relationships.  This feature can be very useful, especially if you are writing an API.  PostSharp actually ships with 3 out-of-the-box constraints for common scenarios: ComponentInternal, InternalImplements, and Internal.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ComponentInternal&lt;/strong&gt; raises a compiler error if the code its applied to is used in a namespaces besides the one it resides in.  For instance:&lt;/p&gt;
&lt;pre&gt;	// NamespaceA
	namespace PostsharpArchitecturalConstraints.API.NamespaceA
	{
		[ComponentInternal(Severity = SeverityType.Error)]
		internal class ApiA
		{
			public string GetFriendsName()
			{
				return "Mr. Friendly";
			}
		}
	}
	
	// NamespaceB
	using PostsharpArchitecturalConstraints.API.NamespaceA;
	namespace PostsharpArchitecturalConstraints.API.NamespaceB
	{
		public class ApiB
		{
			public string GetFriendsName()
			{
				var a = new ApiA();
				return a.GetFriendsName();
			}
		}
	}
&lt;/pre&gt;
&lt;p&gt;&lt;img src="http://www.sharpcrafters.com/blog/image.axd?picture=30c76ef832bdf6b5.png" alt="Component Internal compiler error" /&gt;&lt;/p&gt;
&lt;p&gt;If you want to specify some exceptions (a specific namespace that you want the internal class to be used in), you can do that in the ComponentInternal's constructor, but by default, it only allows code within its own namespace (and child namespaces) to call it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;InternalImplements&lt;/strong&gt; is for use on interfaces, and limits implementations of the interface to its own assembly.  This means the interface can stay public, for instance, but nothing outside the assembly can implement it.&lt;/p&gt;
&lt;pre&gt;	// in PostsharpArchitecturalConstraints.API assembly
	namespace PostsharpArchitecturalConstraints.API.Interface
	{
		[InternalImplement(Severity = SeverityType.Error)]
		public interface IPublicInterface
		{
			void DoOperation();
			string GetValue();
		}
	}

	// in PostsharpArchitecturalConstraints assembly
	using PostsharpArchitecturalConstraints.API.Interface;

	namespace PostsharpArchitecturalConstraints.Models.Services
	{
		public class MyPublicInterfaceImpl : IPublicInterface
		{
			private string _value;

			public void DoOperation()
			{
				_value = "operation complete";
			}

			public string GetValue()
			{
				return _value;
			}
		}
	}
&lt;/pre&gt;
&lt;p&gt;&lt;img src="http://www.sharpcrafters.com/blog/image.axd?picture=4b66000a03f68c71.png" alt="InternalImplement compiler error" /&gt;&lt;/p&gt;
&lt;p&gt;Why would you want to do this?  If you are designing an API, you may want the user to be able to reference an interface, and use your provided implementations of that interface, but you also may want to &lt;em&gt;change&lt;/em&gt; your interface somewhere down the line.  But, if you make changes to your interface, you could potentially break any implementations that the user has already made.  By using InternalImplement, the user retains some flexibility in how they consume your API without the potential of their code breaking when they upgrade to your new version.&lt;/p&gt;
&lt;p&gt;And finally, &lt;strong&gt;Internal&lt;/strong&gt;.  If you put Internal on a public item, it will remain public, but cannot be used by another assembly.&lt;/p&gt;
&lt;pre&gt;	// in one assembly
	[Internal]
	public class PublicAndInternal
	{
		public string GetValue()
		{
			return "this can only be called in its own assembly";
		}
	}

	// in another assembly
	public class TryingToUseInternal
	{
		public string Execute()
		{
			var publicInternal = new PublicAndInternal();
			return publicInternal.GetValue();
		}
	}
&lt;/pre&gt;
&lt;p&gt;&lt;img src="http://www.sharpcrafters.com/blog/image.axd?picture=5aea7c3c1ac7589e.png" alt="Internal compiler error" /&gt;&lt;/p&gt;
&lt;p&gt;Of course, the door is wide open for you to write your own referential constraints.  Here's one I wrote called Unsealable.  It makes any classes inherited from the selected class unable to be sealed.&lt;/p&gt;
&lt;pre&gt;    [MulticastAttributeUsage(MulticastTargets.Class)]
    public class Unsealable : ReferentialConstraint
    {
        public override void ValidateCode(object target,
			System.Runtime.InteropServices._Assembly assembly)
        {
            var targetType = (Type) target;
            var sealedSubClasses = ReflectionSearch.GetDerivedTypes(targetType)
                                        .Where(t =&amp;gt; t.DerivedType.IsSealed)
                                        .Select(t =&amp;gt; t.DerivedType)
                                        .ToList();
            sealedSubClasses.ForEach(sealedSubClass =&amp;gt; Message.Write(
				MessageLocation.Of(sealedSubClass), 
				SeverityType.Error,
				"997",
				"Error on {0}: subclasses of {1} cannot be sealed.",
				sealedSubClass.FullName, targetType.FullName));
        }
    }
&lt;/pre&gt;
&lt;p&gt;This example also makes use of the handy ReflectionSearch utility that comes with PostSharp, which makes certain reflection tasks (like finding derived types in the above example) cleaner, easier, and Linq-ready.  Here's an example of applying that constraint:&lt;/p&gt;
&lt;pre&gt;	[Unsealable]
	public class MyUnsealableClass
	{
		protected string _value;

		public MyUnsealableClass()
		{
			_value = "I'm unsealable!";
		}

		public string GetValue()
		{
			return _value;
		}
	}

	public sealed class TryingToSeal : MyUnsealableClass
	{
		public TryingToSeal()
		{
			_value = "I'm sealed!";
		}
	}
&lt;/pre&gt;
&lt;p&gt;&lt;img src="http://www.sharpcrafters.com/blog/image.axd?picture=261c8b072a21b0d6.png" alt="Unsealable error" /&gt;&lt;/p&gt;
&lt;p&gt;Constraints can be very valuable for larger teams, or for building an API that will be consumed by a larger audience (even an internal one).  Don't go too crazy, though.  Only build constraints that will help you, your team, and your API consumers save time and make less mistakes.  By enforcing constraints on how code is to be used, you can protect yourself and your users from costly breaking changes down the road.  It may be a politically sensitive issue, so good communication is still important, but it's very much like defensive programming, just at the architectual design level.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=SPbC-A1rUgg:ruxaklLixKs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=SPbC-A1rUgg:ruxaklLixKs:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=SPbC-A1rUgg:ruxaklLixKs:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=SPbC-A1rUgg:ruxaklLixKs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=SPbC-A1rUgg:ruxaklLixKs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=SPbC-A1rUgg:ruxaklLixKs:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=SPbC-A1rUgg:ruxaklLixKs:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=SPbC-A1rUgg:ruxaklLixKs:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=SPbC-A1rUgg:ruxaklLixKs:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=SPbC-A1rUgg:ruxaklLixKs:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=SPbC-A1rUgg:ruxaklLixKs:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=SPbC-A1rUgg:ruxaklLixKs:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/postsharp/~4/SPbC-A1rUgg" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Matthew Groves</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/post.aspx?id=1d4a11da-1e25-4b14-9886-b74d1a3e263c</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">3</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.sharpcrafters.com/blog/trackback.axd?id=1d4a11da-1e25-4b14-9886-b74d1a3e263c</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/post/Architectural-Validation.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/syndication.axd?post=1d4a11da-1e25-4b14-9886-b74d1a3e263c</wfw:commentRss><feedburner:origLink>http://www.sharpcrafters.com/blog/post.aspx?id=1d4a11da-1e25-4b14-9886-b74d1a3e263c</feedburner:origLink></item><item><title>What’s New in PostSharp 2.1: Support for Obfuscation (Dotfuscator)</title><link>http://feedproxy.google.com/~r/postsharp/~3/YQtGNgrHAeo/post.aspx</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Gael Fraiteur</dc:creator><pubDate>Mon, 25 Jul 2011 10:42:32 PDT</pubDate><guid isPermaLink="false">http://www.sharpcrafters.com/blog/post.aspx?id=f93091b7-4b43-403a-9407-f01ff3b16dc3</guid><description>&lt;p&gt;With prior versions of PostSharp, you had to be very careful to make your software compatible with any obfuscator. You could not obfuscate aspect classes, you could not store reflection objects, and you could not add use a reflection object in RuntimeInitialize with obfuscated generic methods. Indeed, all these features caused PostSharp to store the name of the metadata objects at build time, and to deserialize it at run time. But since the obfuscator renamed metadata objects after build time, the deserialization failed. Briefly said, previous versions of PostSharp were incompatible with all obfuscators.&lt;/p&gt;  &lt;p&gt;PostSharp 2,1 provides a mechanism through which assemblies can be “repaired” after they have been obfuscated. Assemblies are still fully obfuscated, but PostSharp provides a utility to repair the name-object table. The build process is the following:&lt;/p&gt;  &lt;p&gt;1. The compiler produces an assembly.&lt;/p&gt;  &lt;p&gt;2. PostSharp post-processes the assembly and embeds an name table in the output assembly.&lt;/p&gt;  &lt;p&gt;3. The obfuscator renames metadata objects, therefore breaks the PostSharp name table.&lt;/p&gt;  &lt;p&gt;4. The post-obfuscation step (implemented by PostSharp) repairs the name table based on the obfuscation map produced by the obfuscator, and mapping the old name to the new name.&lt;/p&gt;  &lt;p&gt;Since the post-obfuscation utility works with the obfuscation map, we need one implementation of this utility for every obfuscation map format, therefore for every obfuscation tool. PostSharp 2.1 includes support for &lt;strong&gt;Dotfuscator&lt;/strong&gt;, the leading obfuscator .NET.&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;Calling the post-obfuscator&lt;/h2&gt;  &lt;p&gt;Let’s see how it works practically. You can &lt;a href="http://www.sharpcrafters.com/downloads/samples/2.1/Obfuscation.zip" target="_blank"&gt;download the example&lt;/a&gt; and try yourself.&lt;/p&gt;  &lt;p&gt;To call the post-obfuscation step, you have to create an MSBuild project file and import the targets &lt;em&gt;AddIns\PostSharp.AddIn.PostObfuscation.targets. &lt;/em&gt;&lt;/p&gt;  &lt;pre&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;
&amp;lt;Project xmlns=&amp;quot;http://schemas.microsoft.com/developer/msbuild/2003&amp;quot; DefaultTargets=&amp;quot;Build&amp;quot;&amp;gt;

  &amp;lt;ItemGroup&amp;gt;
    &amp;lt;!-- Required: Path of dependencies of obfuscated assemblies. --&amp;gt;
    &amp;lt;ObfuscatedSearchPath Include=&amp;quot;Dotfuscated&amp;quot; /&amp;gt;
    &amp;lt;!-- Required: Path of dependencies of unobfuscated assemblies. --&amp;gt;
    &amp;lt;UnobfuscatedSearchPath Include=&amp;quot;Unobfuscated&amp;quot;/&amp;gt;
    &amp;lt;!-- Required: Obfuscation map file produced by Dotfuscator. --&amp;gt;
    &amp;lt;MapFile Include=&amp;quot;Dotfuscated\Map.xml&amp;quot;/&amp;gt;
    &amp;lt;!-- Required: Obfuscated files --&amp;gt;
    &amp;lt;ObfuscatedAssembly Include=&amp;quot;Dotfuscated\*.dll&amp;quot;/&amp;gt;
    &amp;lt;ObfuscatedAssembly Include=&amp;quot;Dotfuscated\*.exe&amp;quot;/&amp;gt;
    &amp;lt;!-- Optional --&amp;gt;
    &amp;lt;ContentFiles Include=&amp;quot;Unobfuscated\*.config&amp;quot;/&amp;gt;
  &amp;lt;/ItemGroup&amp;gt;

  &amp;lt;PropertyGroup&amp;gt;
    &amp;lt;!-- Required: output directory --&amp;gt;
    &amp;lt;OutputPath&amp;gt;$(MSBuildProjectDirectory)\Remapped&amp;lt;/OutputPath&amp;gt;
    &amp;lt;!-- Required: selection of the remapping strategy --&amp;gt;
    &amp;lt;Obfuscator&amp;gt;Dotfuscator&amp;lt;/Obfuscator&amp;gt;
  &amp;lt;/PropertyGroup&amp;gt;


  &amp;lt;Target Name=&amp;quot;Build&amp;quot; DependsOnTargets=&amp;quot;PostObfuscationRemap&amp;quot;&amp;gt;
    &amp;lt;!-- Optional: copy other files to the output directory--&amp;gt;
    &amp;lt;Copy SourceFiles=&amp;quot;@(ContentFiles)&amp;quot; DestinationFolder=&amp;quot;$(OutputPath)&amp;quot;/&amp;gt;
  &amp;lt;/Target&amp;gt;

  &amp;lt;Target Name=&amp;quot;Rebuild&amp;quot; DependsOnTargets=&amp;quot;Clean;Build&amp;quot;&amp;gt;
  &amp;lt;/Target&amp;gt;
  
  &amp;lt;Import Project=&amp;quot;..\..\Build\bin\AddIns\PostSharp.AddIn.PostObfuscation.targets&amp;quot; /&amp;gt;
&amp;lt;/Project&amp;gt;&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;As you can see, this file defines some locations (required items and properties), and calls the &lt;em&gt;PostObfuscationRemap&lt;/em&gt; target defined in &lt;em&gt;PostSharp.AddIn.PostObfuscation.targets&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;&lt;/h2&gt;

&lt;h2&gt;Safe code references&lt;/h2&gt;

&lt;p&gt;The post-obfuscator ensures the following references to code are repaired after obfuscation:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;References you are not aware of (used by PostSharp to provide the runtime features).&lt;/li&gt;

  &lt;li&gt;Reflection objects (for instance MethodInfo, Type) serialized inside objects using the default serializer (BinaryFormatter). This feature is implemented thanks to serialization surrogates for reflection objects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is no magic. Other strings referencing to a metadata element, and stored somewhere else than in a reflection object serialized by the default serializer, will not be fixed. If you wrote your custom aspect serializer and want to take advantage of metadata reference serialization, you have to play with &lt;em&gt;IMetadataEmitter&lt;/em&gt;/&lt;em&gt;IMetadataDispenser&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;In other words, if you want to write obfuscation-safe aspects, the only serialized metadata references should be reflection objects in an aspect field (or somewhere under an aspect field).&lt;/p&gt;

&lt;h2&gt;Stripping of events and properties&lt;/h2&gt;

&lt;p&gt;Dotfuscator allows users to remove events and properties from code. The reason is simple: they are useless at runtime for the CLR. They are pure compiler syntactic sugar… or rather were, before XAML. So what if your aspect stores a &lt;em&gt;PropertyInfo&lt;/em&gt; or &lt;em&gt;EventInfo&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;PostSharp will be smart enough to provide you with a &lt;em&gt;PropertyInfo &lt;/em&gt;or &lt;em&gt;EventInfo. &lt;/em&gt;The only visible difference is that the &lt;em&gt;Name&lt;/em&gt; property will return &lt;em&gt;null&lt;/em&gt;. Other properties and methods will work as usually. Under the hood, PostSharp will give you an object of type &lt;em&gt;ObfuscatedPropertyInfo&lt;/em&gt; or &lt;em&gt;ObfuscatedEventInfo&lt;/em&gt; instead of &lt;em&gt;RuntimePropertyInfo&lt;/em&gt; or &lt;em&gt;RuntimeEventInfo&lt;/em&gt;, but your code should not see the difference.&lt;/p&gt;

&lt;h2&gt;Support for other obfuscators&lt;/h2&gt;

&lt;p&gt;As a first step, we provide support for Dotfuscator. If other vendors are interested to support PostSharp, we’ll gladly provide them with the specification of the binary format. If you want to contribute a post-obfuscation filter, then be pleased that the Dotfuscator-specific code is only 56 lines long (parsing of their XML obfuscation map). The post-obfuscation add-in is not obfuscated so feel free to use a decompiler :).&lt;/p&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;That’s it for obfuscation. A small, unexciting feature, but people who need to obfuscate their applications don’t have any excuse not to use PostSharp!&lt;/p&gt;

&lt;p&gt;Happy PostSharping!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=YQtGNgrHAeo:AyQ1m44Sics:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=YQtGNgrHAeo:AyQ1m44Sics:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=YQtGNgrHAeo:AyQ1m44Sics:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=YQtGNgrHAeo:AyQ1m44Sics:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=YQtGNgrHAeo:AyQ1m44Sics:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=YQtGNgrHAeo:AyQ1m44Sics:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=YQtGNgrHAeo:AyQ1m44Sics:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=YQtGNgrHAeo:AyQ1m44Sics:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=YQtGNgrHAeo:AyQ1m44Sics:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=YQtGNgrHAeo:AyQ1m44Sics:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=YQtGNgrHAeo:AyQ1m44Sics:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=YQtGNgrHAeo:AyQ1m44Sics:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/postsharp/~4/YQtGNgrHAeo" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Gael Fraiteur</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/post.aspx?id=f93091b7-4b43-403a-9407-f01ff3b16dc3</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">3</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.sharpcrafters.com/blog/trackback.axd?id=f93091b7-4b43-403a-9407-f01ff3b16dc3</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/post/Whate28099s-New-in-PostSharp-21-Support-for-Obfuscation-(Dotfuscator).aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/syndication.axd?post=f93091b7-4b43-403a-9407-f01ff3b16dc3</wfw:commentRss><feedburner:origLink>http://www.sharpcrafters.com/blog/post.aspx?id=f93091b7-4b43-403a-9407-f01ff3b16dc3</feedburner:origLink></item><item><title>New in PostSharp 2.1: Navigating Code Relationships</title><link>http://feedproxy.google.com/~r/postsharp/~3/bPQzWSDAvks/post.aspx</link><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Gael Fraiteur</dc:creator><pubDate>Fri, 22 Jul 2011 05:41:11 PDT</pubDate><guid isPermaLink="false">http://www.sharpcrafters.com/blog/post.aspx?id=d2290b06-efd2-4f7a-aa22-f0648ffc3941</guid><description>&lt;p&gt;&lt;a href="http://www.sharpcrafters.com/blog/post/New-in-PostSharp-21-Reflecting-Custom-Attributes.aspx" target="_blank"&gt;In my previous post&lt;/a&gt;, I introduced the new class &lt;em&gt;ReflectionSearch&lt;/em&gt; and two of its methods: &lt;em&gt;GetCustomAttributesOfType&lt;/em&gt; and &lt;em&gt;GetCustomAttributesOnTarget&lt;/em&gt;. These methods give access to PostSharp’s internal repository of custom attributes.&lt;/p&gt;  &lt;p&gt;Today, I would like to cover the second feature of &lt;em&gt;ReflectionSearch&lt;/em&gt;: querying the relationships between elements of code. Three kinds of relationships are supported:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;type inheritance (classes and interfaces), &lt;/li&gt;    &lt;li&gt;usage in statements (a type, method, or field is used inside a method body), &lt;/li&gt;    &lt;li&gt;member type, &lt;/li&gt;    &lt;li&gt;any of the above, but as a type element (described below). &lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;Navigating Type Inheritance&lt;/h2&gt;  &lt;p&gt;The system reflection API makes it easy to navigate from a child class to its parents, but the opposite is not true: if you want to retrieve all classes implementing a given interface in the assembly, you have to enumerate all types in this assembly, then enumerate all implemented interfaces, and do a recursion on the parent type. As was the case in the previous post with custom attributes, PostSharp indexes the type hierarchy for internal use. From PostSharp 2.1, &lt;em&gt;ReflectionSearch&lt;/em&gt; exposes this feature to high-level aspects, and it comes with no performance cost.&lt;/p&gt;  &lt;p&gt;The method &lt;em&gt;ReflectionSearch.GetDerivedTypes&lt;/em&gt; does what it says, with one remark: by default, it returns only first-level derived types, i.e. it does not return derived types of derived types. If you want a deep search, you have to specify the option &lt;em&gt;ReflectionSearchOptions.IncludeDerivedTypes&lt;/em&gt;. &lt;/p&gt;  &lt;p&gt;Note that the method does not return an array of types, but of &lt;em&gt;TypeInheritanceCodeReference&lt;/em&gt;. This object provides information about the base type. You may think the base type is always what you passed in the argument, but it isn’t always true. Consider the following code:&lt;/p&gt;  &lt;pre&gt;class GenericCollection&amp;lt;T&amp;gt; : ICollection&amp;lt;T&amp;gt; {}

class IntCollection : GenericCollection&amp;lt;int&amp;gt; {}

TypeInheritanceCodeReference[] derivedTypes = &lt;br /&gt;      ReflectionSearch.GetDerivedTypes( typeof(ICollection&amp;lt;&amp;gt;);&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;In this case, &lt;em&gt;GetDerivedTypes&lt;/em&gt; would return two pairs: (&lt;em&gt;GenericCollection&amp;lt;T&amp;gt;, ICollection&amp;lt;T&amp;gt;)&lt;/em&gt; and (&lt;em&gt;IntCollection, ICollection&amp;lt;int&amp;gt;&lt;/em&gt;). In each case, the base type is a different instance of the generic type.&lt;/p&gt;

&lt;h2&gt;Navigating Usage&lt;/h2&gt;

&lt;p&gt;As a part of the post-compilation process, PostSharp scans all method bodies and builds a bi-directional map of using/used-by relationships, i.e. it determines which fields, methods or type are used in statements and expressions of a method body, and creates an index. This functionality is now available inside &lt;em&gt;PostSharp.dll&lt;/em&gt; and is exposed on two methods:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;ReflectionSearch.GetDeclarationsUsedByMethod&lt;/em&gt; returns the set of fields, methods and types used by a given method. &lt;/li&gt;

  &lt;li&gt;&lt;em&gt;ReflectionSearch.GetMethodsUsingDeclaration&lt;/em&gt; returns all methods using a given field, method, or type. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can note, it is not possible to query references to properties and events. Indeed, properties and events are compiler “syntactic sugar” and are never referred to by instructions at MSIL level. If you want to query properties or events, you have to query each accessor separately (add, remove, get, set).&lt;/p&gt;

&lt;p&gt;These methods return an array of &lt;em&gt;MethodUsageCodeReference&lt;/em&gt;. This object contains both ends of the relationship, as well as a bit mask telling which instructions the declaration was used with – so you can distinguish between a get or a set operation on a field.&lt;/p&gt;

&lt;h2&gt;Navigating Member Types&lt;/h2&gt;

&lt;p&gt;The last thing you can do with &lt;em&gt;ReflectionSearch&lt;/em&gt; is to get a list of all members of a given type. By member, I mean a field, a property, an event, a parameter, or a return-value parameter.&lt;/p&gt;

&lt;p&gt;This feature is exposed on &lt;em&gt;ReflectionsSearch.GetMembersOfType&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Note that PostSharp does &lt;em&gt;not&lt;/em&gt; use this feature internally, so there is an additional performance cost in calling that method. The first time you invoke &lt;em&gt;GetMembersOfType&lt;/em&gt;, the assembly will be scanned and indexed (using PostSharp’s internal APIes, not System.Reflection).&lt;/p&gt;

&lt;h2&gt;Type Elements&lt;/h2&gt;

&lt;p&gt;By default, all methods of &lt;em&gt;ReflectionSearch&lt;/em&gt; match the exact type passed as an argument (or match derived types if &lt;em&gt;ReflectionSearchOptions.IncludeDerivedTypes&lt;/em&gt; is specified). However, there are cases where you want a larger choice.&lt;/p&gt;

&lt;p&gt;Consider the following code:&lt;/p&gt;

&lt;pre&gt;class Bar {}

class Foo : ICollection&amp;lt;Bar&amp;gt;
{
   Bar[] array;

   void ICollection&amp;lt;Bar&amp;gt; FooBar()
   {
     return new List&amp;lt;Bar&amp;gt;();
   }
}

var derivedTypes = ReflectionSearch.GetDerivedTypes( typeof(Bar), options );
var members = ReflectionSearch.GetMembersOfType( typeof(Bar), options );
var usages = ReflectionSearch.GetMethodsUsingDeclaration( typeof(Bar), options );&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;With the default value of &lt;em&gt;options&lt;/em&gt;, the three methods return an empty set. Indeed, there is no type derived from &lt;em&gt;Bar&lt;/em&gt;, no field or return value of type &lt;em&gt;Bar&lt;/em&gt;, and no instruction using &lt;em&gt;Bar&lt;/em&gt;. However, if you include the option &lt;em&gt;ReflectionSearchOptions.IncludeTypeElement&lt;/em&gt;, you will get:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;as derived type: &lt;em&gt;Foo,&lt;/em&gt;&lt;/li&gt;

  &lt;li&gt;as members: the field &lt;em&gt;array&lt;/em&gt; and the return value of &lt;em&gt;FooBar&lt;/em&gt;, and&lt;/li&gt;

  &lt;li&gt;as usages: the method &lt;em&gt;FooBar&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;em&gt;IncludeTypeElement&lt;/em&gt; option asks PostSharp to index at a much deeper level. Pay attention: this comes at a performance cost. PostSharp does not use this feature internally, so the first time you use the option, it will have to scan all type signatures and build an index.&lt;/p&gt;

&lt;h2&gt;&lt;/h2&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;The new &lt;em&gt;ReflectionSearch&lt;/em&gt; class allows you to make complex queries over System.Reflection. Most of the times, the features are already used internally by PostSharp, so they come at minimal performance cost. &lt;/p&gt;

&lt;p&gt;The &lt;em&gt;ReflectionSearch&lt;/em&gt; class is accessible at build time only. The primary use case is to write more powerful logic for &lt;em&gt;IAspectProvider&lt;/em&gt; or &lt;em&gt;MethodPointcut&lt;/em&gt;. The second use case is to validate your code. And this is for another blog post.&lt;/p&gt;

&lt;p&gt;Happy PostSharping!&lt;/p&gt;

&lt;p&gt;-gael&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=bPQzWSDAvks:Gq_qr-EJs1Q:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=bPQzWSDAvks:Gq_qr-EJs1Q:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=bPQzWSDAvks:Gq_qr-EJs1Q:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=bPQzWSDAvks:Gq_qr-EJs1Q:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=bPQzWSDAvks:Gq_qr-EJs1Q:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=bPQzWSDAvks:Gq_qr-EJs1Q:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=bPQzWSDAvks:Gq_qr-EJs1Q:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=bPQzWSDAvks:Gq_qr-EJs1Q:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=bPQzWSDAvks:Gq_qr-EJs1Q:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=bPQzWSDAvks:Gq_qr-EJs1Q:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=bPQzWSDAvks:Gq_qr-EJs1Q:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=bPQzWSDAvks:Gq_qr-EJs1Q:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/postsharp/~4/bPQzWSDAvks" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Gael Fraiteur</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/post.aspx?id=d2290b06-efd2-4f7a-aa22-f0648ffc3941</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">3</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.sharpcrafters.com/blog/trackback.axd?id=d2290b06-efd2-4f7a-aa22-f0648ffc3941</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/post/New-in-PostSharp-21-Navigating-Code-Relationships.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/syndication.axd?post=d2290b06-efd2-4f7a-aa22-f0648ffc3941</wfw:commentRss><feedburner:origLink>http://www.sharpcrafters.com/blog/post.aspx?id=d2290b06-efd2-4f7a-aa22-f0648ffc3941</feedburner:origLink></item><item><title>New in PostSharp 2.1: Reflecting Custom Attributes</title><link>http://feedproxy.google.com/~r/postsharp/~3/uWlADydW-sk/post.aspx</link><category>Tutorial</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Gael Fraiteur</dc:creator><pubDate>Thu, 21 Jul 2011 07:41:03 PDT</pubDate><guid isPermaLink="false">http://www.sharpcrafters.com/blog/post.aspx?id=82e65947-e0e6-4d38-ba08-c1a190613124</guid><description>&lt;p&gt;One of the breaking innovations of PostSharp 1.0 in 2005 was the ability to execute aspect code at build time. Whereas other AOP frameworks developed complex declarative syntaxes to express “pointcuts”, PostSharp just allowed you to use System.Reflection to select the target of aspects. LINQ made it even easier to express complex code queries.&lt;/p&gt;  &lt;p&gt;Yet, some queries were difficult to achieve just with System.Reflection. For instance, it is fairly difficult and inefficient to get all properties annotated with the [DataMember] custom attribute: you have to enumerate all types (and do a recursion on nested types), get all properties of these types, and check the presence of this custom attribute on all properties. Wow. If we were querying a relational database, we would probably create an index on the &lt;em&gt;Type&lt;/em&gt; column of the &lt;em&gt;CustomAttribute &lt;/em&gt;table. Well, the analogy is not so stupid. Metadata in a .NET assembly is in fact a relational database, and there is a &lt;em&gt;CustomAttribute&lt;/em&gt; table. What is more, PostSharp already builds these indexes internally. So why not making them available to user code? This was the principal idea behind this new feature: &lt;strong&gt;reflection search&lt;/strong&gt;.&lt;/p&gt;  &lt;p&gt;Reflection Search is simply this: a set of methods making it easier and more efficient to query metadata of the assembly being processed by PostSharp. Therefore, this API is available &lt;em&gt;only at build time&lt;/em&gt;.&amp;#160; It is not intended to “improve” System.Reflection for run-time use. That said, if you need to do some complex reflection query at runtime, it’s better to do it at build time using PostSharp, serialize the result and store it as a managed resource.&lt;/p&gt;  &lt;p&gt;The API is exposed in the class &lt;em&gt;PostSharp.Reflection.ReflectionSearch&lt;/em&gt;. Note that the feature is available in the Professional Edition only.&lt;/p&gt;  &lt;h2&gt;Enumerating Custom Attributes&lt;/h2&gt;  &lt;h3&gt;Custom attributes of a type&lt;/h3&gt;  &lt;p&gt;The first set of methods you will find on the &lt;em&gt;ReflectionSearch&lt;/em&gt; class allow you to enumerate custom attributes. &lt;em&gt;GetCustomAttributesOnType&lt;/em&gt; retrieve all custom attributes of a given type in the current assembly (remember that this works only at build time, so the notion of “current assembly” refers to the assembly being processed by PostSharp). The second overload takes an additional parameter &lt;em&gt;ReflectionSearchOptions&lt;/em&gt;. If you specify the value &lt;em&gt;IncludeDerivedTypes&lt;/em&gt;, you will get all custom attributes of the specified type &lt;em&gt;or&lt;/em&gt; any type derived from it.&lt;/p&gt;  &lt;p&gt;There is no example in the system class library to illustrate a hierarchy of custom attributes, so let's create our own:&lt;/p&gt;  &lt;pre&gt;// A hierarchy of custom attributes.

class FruitAttribute : Attribute {}

class AppleAttribute  : FruitAttribute {}

class OrangeAttribute : FruitAttribute {}

class VegetableAttribute : Attribute {}

class TomatoAttribute : VegetableAttribute {}

// Using the custom attributes

[Fruit]
class Team
{
   [Apple]
   Dude tom;

   [Orange]  
   Dude jerry;

   [Tomato]
   Dude donald;

}

// Enumerating the custom attributes (build-time)
class MyAspect : AssemblyLevelAspect, IAspectProvider
{
 
    public IEnumerable&lt;aspectinstance&gt; ProvideAspects(object target)
    {

      CustomAttributeInstances[] attributes = ReflectionSearch.GetCustomAttributesOfType( &lt;br /&gt;          typeof(FruitAttribute), ReflectionSearchOptions.IncludeDerivedTypes );

      // TODO: Do something with that.

    }

}&lt;/pre&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;The method &lt;em&gt;GetCustomAttributesType&lt;/em&gt; will return three instances of the custom attribute: &lt;em&gt;(FruitAttribute&lt;/em&gt;, &lt;em&gt;Team&lt;/em&gt;), (&lt;em&gt;AppleAttribute &lt;/em&gt;,&lt;em&gt;Team.tom&lt;/em&gt;) and &lt;em&gt;(OrangeAttribute, Team.jerry&lt;/em&gt;). &lt;/p&gt;

&lt;p&gt;If you wonder why the method does not return a tomato: it is by decision of the U.S. Supreme Court, which, on May 10, 1893, declared that tomatoes are vegetables because – although they are classified as fruits in botany –&amp;#160; &lt;a href="http://en.wikipedia.org/wiki/Tomato#Fruit_or_vegetable.3F"&gt;they are usually served with dinner and not dessert&lt;/a&gt;. As far as I am concerned, I still don’t eat tomatoes for dessert, the only thing that changed is that we are now much more accustomed to bureaucracy (and today’s tomatoes have better resistance to pressure because the species were selected to accommodate mechanical picking, and long storage and transportation – so arguably we now eat more tomatoes than in the XIX&lt;sup&gt;th&lt;/sup&gt; century, but they are probably less tasty).&lt;/p&gt;

&lt;p&gt;Anyway.&lt;/p&gt;

&lt;p&gt;Note that the method returns a &lt;em&gt;CustomAttributeInstance&lt;/em&gt;, which includes information about the custom attribute and the element of code to which it is applied.&lt;/p&gt;

&lt;h3&gt;Multicast attributes&lt;/h3&gt;

&lt;p&gt;Keep in mind that &lt;em&gt;ReflectionSearch&lt;/em&gt; reflects the internal repository of custom attributes. This repository does not only include custom attributes that you add to your code manually. It also includes all “pseudo” custom attributes added by different components of PostSharp, starting with multicast attributes (remember that aspect class typically derive from MulticastAttribute).&lt;/p&gt;

&lt;p&gt;When you use multicast custom attributes in your code, PostSharp executes the multicasting algorithm to populate the internal repository. The repository then contains the &lt;em&gt;concrete instances&lt;/em&gt; of the custom attribute. &lt;/p&gt;

&lt;p&gt;Let’s take an example:&lt;/p&gt;

&lt;pre&gt;[MulticastAttributeUsage( MulticastTargets.Method )]
class FooAttribute : MulticastAttribute {}

[Foo]
class MyClass
{
   void MyMethod() {}
}&lt;/pre&gt;

&lt;p&gt;In that case the repository contains an instance of &lt;em&gt;FooAttribute&lt;/em&gt; on &lt;em&gt;MyMethod&lt;/em&gt; but &lt;strong&gt;not&lt;/strong&gt; on &lt;em&gt;MyClass&lt;/em&gt;. The normal reflection API would give the opposite result (at least when it is run inside PostSharp or before PostSharp), because it is not aware of multicast semantics.&lt;/p&gt;

&lt;p&gt;Since you can’t use normal reflection to retrieve multicast custom attributes, &lt;em&gt;ReflectionSearch&lt;/em&gt; offers a second method: &lt;em&gt;GetCustomAttributesOnTarget&lt;/em&gt;. As the name suggests, it returns the list of all custom attributes on a given element of code.&lt;/p&gt;

&lt;h2&gt;&lt;/h2&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;The high-level library &lt;em&gt;PostSharp.dll&lt;/em&gt; now offers access to the internal repository of custom attributes. Since this repository, and all indexes, are used by PostSharp itself, using this new feature has minimal impact on build time. Now, you have a way to query custom attributes by type without killing performance. And you are finally able to query attributes that were created by PostSharp as the result of the multicasting algorithm.&lt;/p&gt;

&lt;p&gt;But that’s not all &lt;em&gt;ReflectionSearch &lt;/em&gt;has to offer. Next in line: browse relationships between elements of code. But this is for another day.&lt;/p&gt;

&lt;p&gt;Happy PostSharping!&lt;/p&gt;

&lt;p&gt;-gael&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=uWlADydW-sk:BsHMj8-zYCE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=uWlADydW-sk:BsHMj8-zYCE:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=uWlADydW-sk:BsHMj8-zYCE:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=uWlADydW-sk:BsHMj8-zYCE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=uWlADydW-sk:BsHMj8-zYCE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=uWlADydW-sk:BsHMj8-zYCE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=uWlADydW-sk:BsHMj8-zYCE:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=uWlADydW-sk:BsHMj8-zYCE:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=uWlADydW-sk:BsHMj8-zYCE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=uWlADydW-sk:BsHMj8-zYCE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=uWlADydW-sk:BsHMj8-zYCE:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=uWlADydW-sk:BsHMj8-zYCE:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/postsharp/~4/uWlADydW-sk" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Gael Fraiteur</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/post.aspx?id=82e65947-e0e6-4d38-ba08-c1a190613124</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">4</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.sharpcrafters.com/blog/trackback.axd?id=82e65947-e0e6-4d38-ba08-c1a190613124</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/post/New-in-PostSharp-21-Reflecting-Custom-Attributes.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/syndication.axd?post=82e65947-e0e6-4d38-ba08-c1a190613124</wfw:commentRss><feedburner:origLink>http://www.sharpcrafters.com/blog/post.aspx?id=82e65947-e0e6-4d38-ba08-c1a190613124</feedburner:origLink></item><item><title>PostSharp Principles: Day 15 – Introducing Members and Interfaces, Part 2</title><link>http://feedproxy.google.com/~r/postsharp/~3/Zk-OBzugDns/post.aspx</link><category>Tutorial</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Dustin Davis</dc:creator><pubDate>Fri, 15 Jul 2011 08:34:00 PDT</pubDate><guid isPermaLink="false">http://www.sharpcrafters.com/blog/post.aspx?id=45d65dee-c96e-4a28-9205-fb64e3e28904</guid><description>&lt;p&gt;Yesterday we introduced members into our target class. Today we&amp;rsquo;re going to go the other way and introduce members from our target class into our aspect for consumption by the process of importing.&lt;/p&gt;
&lt;h3&gt;Importing Members&lt;/h3&gt;
&lt;p&gt;There are cases when you will need to bring in a field or method from a target class so that you have access to it from within the aspect. What we&amp;rsquo;re doing is making assumptions about the target. It&amp;rsquo;s important to document what the aspect is assuming about the target code. Another approach instead of importing, is to cast the instance to a interface (or type) known to be implemented on the target.&lt;/p&gt;
&lt;p&gt;To import, we use the ImportMember attribute. ImportMember allows us to import fields, properties, methods and events. As an example, let&amp;rsquo;s look at some sample code.&lt;/p&gt;
&lt;pre&gt;public interface IIdentifiable
{
    Guid ID { get; }
    void PrintID();

}

public class ExampleClass : IIdentifiable
{
    public Guid ID { get; private set; } //Satisfy the interface

    public ExampleClass()
    {
        this.ID = Guid.NewGuid();
    }

    [ImportExampleAspect]
    public void DoWork()
    {
        Console.WriteLine("Doing work");
    }

    public void PrintID()
    {
        Console.WriteLine(this.ID.ToString());
    }

}

[Serializable]
public class ImportExampleAspect : OnMethodBoundaryAspect, IInstanceScopedAspect
{
    [ImportMember("PrintID", IsRequired = true)]
    public Action PrintID;

    [ImportMember("ID")]
    public Property IDFromClass;

    public override void OnEntry(MethodExecutionArgs args)
    {
        Guid value = IDFromClass.Get();
        PrintID();
        Console.WriteLine("Value from IIdentifiable.ID is {0}", value.ToString());
    }

    public object CreateInstance(AdviceArgs adviceArgs)
    {
        return this.MemberwiseClone();
    }

    public void RuntimeInitializeInstance() {}

}&lt;/pre&gt;
&lt;p&gt;We have an example class that implements a simple interface and an aspect based on OnMethodBoundaryAspect. When you run this example code, the value of the &amp;lsquo;ID&amp;rsquo; property will be written to the console.&lt;/p&gt;
&lt;pre&gt;178411e1-c79b-43fc-9aa0-ff309425abaa
Value from IIdentifiable.ID is 178411e1-c79b-43fc-9aa0-ff309425abaa
Doing work&lt;/pre&gt;
&lt;p&gt;Notice that our aspect implements the IInstanceScopedAspect interface. ImportMember cannot import static fields so we have to define our aspect as instance scoped. For more information on the life time and scope of aspects, refer to &lt;a href="http://www.sharpcrafters.com/blog/post/Day-9-Aspect-Lifetime-Scope-Part-1.aspx"&gt;Day 9&lt;/a&gt; and &lt;a href="http://www.sharpcrafters.com/blog/post/Day-10-Aspect-Lifetime-Scope-Part-2.aspx"&gt;Day 10&lt;/a&gt; of the PostSharp Principals series.&lt;/p&gt;
&lt;p&gt;We expect the target to implement the interface which has a PrintID method defined. So we setup a public Action and we call it PrintID. We decorate our Action with the ImportMember attribute passing in the target&amp;rsquo;s member name which is &amp;lsquo;PrintID&amp;rsquo;.&lt;/p&gt;
&lt;p&gt;Next we defined the IDFromClass public field of type Property&amp;lt;Guid&amp;gt;. This class has two properties: Get and Set. At runtime, the Get and Set properties will contain a delegate to the getter and setter of this property. In order to import an event, we need a public field of type Event&amp;lt;EventArgs&amp;gt;, which has two delegate properties: Add and Remove.&lt;/p&gt;
&lt;p&gt;We do not have to use the same name as the target&amp;rsquo;s member name, so instead of &amp;lsquo;ID&amp;rsquo; we are using &amp;lsquo;IDFromClass&amp;rsquo;.Inside of the OnEntry method we get the value of ID from our target class using the Get delegate provided by IDFromClass, make a call to the PrintID method and then write out the value to the console.&lt;/p&gt;
&lt;p&gt;Note: ImportMember will work on members of any visibility, even private.&lt;/p&gt;
&lt;h3&gt;ImportMemberAttribute&lt;/h3&gt;
&lt;p&gt;There should be no surprise when I say that we can control the behavior of the import using the attribute&amp;rsquo;s parameters.&lt;/p&gt;
&lt;h4&gt;IsRequired&lt;/h4&gt;
&lt;p&gt;Specifies whether the member being imported is required or not. If true, a compiler error will occur if the member is not present in the target class. If false, the reference to the member will be null if it does not exist in the target.&lt;/p&gt;
&lt;h4&gt;Order&lt;/h4&gt;
&lt;p&gt;Order takes an enumeration from PostSharp.Aspects.Advices.ImportMemberOrder to determine when the importing will occur.&lt;/p&gt;
&lt;p&gt;&amp;middot; AfterIntroductions (default) &amp;ndash; Importing will occur only after the aspect has introduced its own members. This is useful if the imported member is virtual and we need to import the last override.BeforeIntroductions &amp;ndash; Importing will occur before any members are introduced by the aspect. This gives you a chance to get a reference to the original member before any overriding occurs. This is similar to calling an overridden method by the &amp;ldquo;base&amp;rdquo; keyword.&lt;/p&gt;
&lt;p&gt;&amp;middot; Default &amp;ndash; The default is AfterIntroductions.&lt;/p&gt;
&lt;p&gt;There can be any number of aspects on the same class that override the same method. Importing before the introductions allows you to call the next node in the chain of overwriting.&lt;/p&gt;
&lt;h3&gt;Better Example&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s have a look at a more in-depth example using both importing and introduction, the MakeDirtyOnChange aspect. When working with workspaces or MDI (multi-document interface) applications, many &amp;ldquo;documents&amp;rdquo; can be open at one time. There is a need to know when one or more of the &amp;ldquo;documents&amp;rdquo; have been modified so that you can inform the user visually and also to know which items need to be updated in the data store. Think about working with five C# files in Visual Studio. When a change is made to a file, you will see an asterisk next to the filename on the file&amp;rsquo;s tab. This is the indication that a change has been made and not yet saved.&lt;/p&gt;
&lt;p&gt;Implementing the IsDirty pattern is similar to the INotifyPropertyChange, the code to wire up the change notification is redundant and tedious. Let&amp;rsquo;s check out our interface and test class before diving into our aspect&lt;/p&gt;
&lt;pre&gt;public interface IsDirty
{
    bool IsDirty { get; }
    event EventHandler WasMadeDirty;
    void ResetDirtyState();
    ReadOnlyCollection DirtyProperties { get; }
}

public class DirtyEventArgs : EventArgs
{
    public string DirtyProperty { get; private set; }

    public DirtyEventArgs(string dirtyProperty)
    {
        this.DirtyProperty = dirtyProperty;
    }
}

[MakeDirtyOnChange]
public class Document
{
    private Guid _docId = Guid.NewGuid();
    public Guid DocId { get { return _docId; } }

    public string Title { get; set; }
    public string Author { get; set; }
    public string Content { get; set; }
}&lt;/pre&gt;
&lt;p&gt;Our IDirty interface has a few requirements that we can and will use to determine if an item has changes. We specify a custom EventArgs class that allows us to provide details about the changes made to the item when invoking the WasMadeDirty event. Our Document class is a clean model that knows nothing about the IsDirty interface.&lt;/p&gt;
&lt;pre&gt;[Serializable]
[IntroduceInterface(typeof(IsDirty), OverrideAction = InterfaceOverrideAction.Ignore)]
public class MakeDirtyOnChange : InstanceLevelAspect, IsDirty
{
    [OnLocationSetValueAdvice, MulticastPointcut(Targets=MulticastTargets.Property)]
    public void OnValueChanged(LocationInterceptionArgs args)
    {
        MakeDirty(args.LocationName);
    }

    private bool _isDirty;
    private List _dirtyProperties;

    [ImportMember("SetDirty")]
    public Action MakeDirty;

    [IntroduceMember(IsVirtual=true, OverrideAction=MemberOverrideAction.Ignore)]
    public void SetDirty(string property)
    {
        _isDirty = true;
        if (WasMadeDirty != null)
        {
            WasMadeDirty.Invoke(this.Instance, new DirtyEventArgs(property));
        }
    }

    #region IsDirty Members

    [IntroduceMember(OverrideAction = MemberOverrideAction.Ignore)]
    public bool IsDirty { get { return _isDirty; } }

    [IntroduceMember(OverrideAction = MemberOverrideAction.Ignore)]
    public ReadOnlyCollection DirtyProperties { get { return _dirtyProperties.AsReadOnly(); } }

    [IntroduceMember(OverrideAction = MemberOverrideAction.Ignore)]
    public event EventHandler WasMadeDirty;

    [IntroduceMember(IsVirtual=true, OverrideAction=MemberOverrideAction.Ignore)]
    public void ResetDirtyState()
    {
        _isDirty = false;
        _dirtyProperties.Clear();
    }
 
    #endregion

    public override void RuntimeInitializeInstance()
    {
        _isDirty = false;
        _dirtyProperties = new List();
    }
}&lt;/pre&gt;
&lt;p&gt;We decorate our aspect with the IntroduceInterface attribute, specifying the IsDirty interface. Our aspect implements the IsDirty interface to satisfy the requirements and then we introduce those members to the target.&lt;/p&gt;
&lt;p&gt;We setup a location interception using OnLocationSetValueAdvice attribute and specify the target is MulticastPointcut.Property ([MARKER, Advice link]). When a property is changed, we&amp;rsquo;re going to invoke the MakeDirty method which we tell PostSharp to import from the target&amp;rsquo;s &amp;ldquo;SetDirty&amp;rdquo; method, if it has one. We&amp;rsquo;re using the defaults for ImportMember which means the import will happen after our members are introduced. Since we&amp;rsquo;re introducing our own SetDirty method, MakeDirty will contain our SetDirty implementation if the target class did not already have its own implementation.&lt;/p&gt;
&lt;p&gt;Since our aspect derives from InstanceLevelAspect we override the RuntimeInitializeInstance method and use it to initialize our private members to their default states.&lt;/p&gt;
&lt;p&gt;We can use the following code to try out the aspect&lt;/p&gt;
&lt;pre&gt;class Program
{
    private static List _changedDocuments = new List();
    private static List _openDocuments = new List();

    static void Main(string[] args)
    {
        for (int i = 0; i &amp;lt; 5; i++)
        {
            Document doc = new Document();
            Post.Cast(doc).WasMadeDirty 
                += new EventHandler(doc_WasMadeDirty);

            _openDocuments.Add(doc);
        }

        _openDocuments[0].Author = "Dustin Davis";
        _openDocuments[0].Title = "PostSharp Principals - Day 1";

        _openDocuments[2].Author = "Dustin Davis";
        _openDocuments[2].Title = "PostSharp Principals - Day 3";

        Console.ReadKey();
    }

    static void doc_WasMadeDirty(object sender, DirtyEventArgs e)
    {
        Document doc = (Document)sender;

        if (_changedDocuments.Any(c =&amp;gt; c.Equals(doc.DocId)))
        {
            return;
        }
            
        _changedDocuments.Add(doc.DocId);
        Console.WriteLine("Document {0} was modified.", doc.DocId);
    }
}&lt;/pre&gt;
&lt;p&gt;The code is pretty straight forward. We create five documents and then add them to our open documents collection. Finally we make changes to two documents. When we run the code, we see the following results&lt;/p&gt;
&lt;pre&gt;Document acbd247a-e742-499e-b27c-ee028e8e6789 was modified.
Document 9ded92cc-008f-48bc-b1b5-e1b0b967e42d was modified.&lt;/pre&gt;
&lt;p&gt;But wait, how are we handling the WasMadeDirty event? I&amp;rsquo;m glad you asked.&lt;/p&gt;
&lt;h3&gt;Post.Cast&amp;lt;&amp;gt;()&lt;/h3&gt;
&lt;p&gt;Post.Cast&amp;lt;&amp;gt;() allows us to cast an instance of a type to &lt;a name="_GoBack"&gt;&lt;/a&gt;another type at design time. For example, our Document class doesn&amp;rsquo;t implement the IsDirty interface so we can&amp;rsquo;t access the IsDirty specific members unless we casting. We use the generic Cast&amp;lt;SourceType, TargetType&amp;gt;(SourceType Instance) method to give us back an instance of TargetType.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s basically nothing more than regular casting, but the difference is when you use Post.Cast&amp;lt;&amp;gt;() you receive compile-time errors if the cast cannot take place. The obvious benefit is that you know right away that the cast fails instead of at run time, potentially introducing bugs.&lt;/p&gt;
&lt;p&gt;In the final result, the call to Post.Cast&amp;lt;&amp;gt;() is replaced with an actual cast.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Previous aspects we looked at have been pretty disconnected from the targets. Being able to introduce and import members gives us a connection and increased flexibility. Being able to automatically introduce interfaces and boiler plate code that is sometimes only consumed at run time frees us and keeps our code clean.&lt;/p&gt;
&lt;div style="padding-bottom: 10px; padding-left: 0px; padding-right: 0px; padding-top: 10px"&gt;&lt;a href="http://www.sharpcrafters.com/blog/image.axd?picture=self573_thumb%5B1%5D_3.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 5px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="self573_thumb[1]" src="http://www.sharpcrafters.com/blog/image.axd?picture=self573_thumb%5B1%5D_thumb_3.jpg" border="0" alt="self573_thumb[1]" width="66" height="66" align="left" /&gt;&lt;/a&gt;Dustin Davis Davis is an enterprise solutions developer and regularly speaks at user groups and code camps. He can be followed on Twitter &lt;a href="http://twitter.com/#!/PrgrmrsUnlmtd"&gt;@PrgrmrsUnlmtd&lt;/a&gt; or his blog &lt;a href="http://www.programmers-unlimited.com"&gt;Programmers-Unlimited.com&lt;/a&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=Zk-OBzugDns:fkpeUNJM400:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=Zk-OBzugDns:fkpeUNJM400:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=Zk-OBzugDns:fkpeUNJM400:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=Zk-OBzugDns:fkpeUNJM400:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=Zk-OBzugDns:fkpeUNJM400:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=Zk-OBzugDns:fkpeUNJM400:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=Zk-OBzugDns:fkpeUNJM400:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=Zk-OBzugDns:fkpeUNJM400:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=Zk-OBzugDns:fkpeUNJM400:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=Zk-OBzugDns:fkpeUNJM400:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=Zk-OBzugDns:fkpeUNJM400:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=Zk-OBzugDns:fkpeUNJM400:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/postsharp/~4/Zk-OBzugDns" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Dustin Davis</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/post.aspx?id=45d65dee-c96e-4a28-9205-fb64e3e28904</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">2</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.sharpcrafters.com/blog/trackback.axd?id=45d65dee-c96e-4a28-9205-fb64e3e28904</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/post/PostSharp-Principals-Day-15-e28093-Introducing-members-and-interfaces-Part-2.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/syndication.axd?post=45d65dee-c96e-4a28-9205-fb64e3e28904</wfw:commentRss><feedburner:origLink>http://www.sharpcrafters.com/blog/post.aspx?id=45d65dee-c96e-4a28-9205-fb64e3e28904</feedburner:origLink></item><item><title>PostSharp Principles: Day 14 – Introducing Members and Interfaces, Part 1</title><link>http://feedproxy.google.com/~r/postsharp/~3/PwTMC1hB2Ho/post.aspx</link><category>Tutorial</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Dustin Davis</dc:creator><pubDate>Thu, 14 Jul 2011 08:28:00 PDT</pubDate><guid isPermaLink="false">http://www.sharpcrafters.com/blog/post.aspx?id=ad025148-6d25-432d-bf1c-567c8186e32c</guid><description>&lt;p&gt;Today we continue our descent into the depths of the PostSharp framework to expose even greater powers to utilize in our projects.&lt;/p&gt;
&lt;h3&gt;Introduction&lt;/h3&gt;
&lt;p&gt;No, not the &amp;ldquo;Hello, my name is Dustin!&amp;rdquo; kind of introduction, but the &amp;ldquo;injection&amp;rdquo; type. What does that mean? PostSharp gives us the power to implement an interface on a class&amp;hellip;at build time. We can also add (introduce) members to that class such as fields/properties, events and methods too. These members are injected at build time and are available at run time.&lt;/p&gt;
&lt;p&gt;Why would you want to do this? As in most cases when applying aspect-oriented programming, you would use this to implement required interfaces that are little more than boilerplate code. One of the most popular examples of interface introduction is the NotifyPropertyChanged aspect which automatically introduces the INotifyPropertyChanged interface and required members. Anyone who has worked with WPF and the MVVM pattern would love to not have to write all of that scaffolding code just to get change notification. Since that aspect uses features we have not yet covered, we will not cover it today. If you&amp;rsquo;re feeling adventurous, you can check it out &lt;a href="http://www.sharpcrafters.com/solutions/notifypropertychanged"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Member Introduction&lt;/h3&gt;
&lt;p&gt;Member introduction allows us to add properties, events and methods to a class. Let&amp;rsquo;s start off by creating an aspect to introduce a property and a method.&lt;/p&gt;
&lt;pre&gt;[Serializable]
public class IntroduceAspect : InstanceLevelAspect
{
    [IntroduceMember]
    public int ID { get; set; }

    [IntroduceMember]
    public void SomeMethod(int param1)
    {
        Console.WriteLine("Inside of introduced method");
    }

}&lt;/pre&gt;
&lt;p&gt;And now our target class&lt;/p&gt;
&lt;pre&gt;[IntroduceAspect]
public class TargetClass
{

}&lt;/pre&gt;
&lt;p&gt;You might be laughing at our test class, but don&amp;rsquo;t worry, our aspect will do the work for us. When we look at the compiled assembly with ILSpy, we see that instead of a blank class we have a few more members than we started with, including the members we wanted to introduce.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.sharpcrafters.com/blog/image.axd?picture=image_20.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" src="http://www.sharpcrafters.com/blog/image.axd?picture=image_thumb_20.png" border="0" alt="image" width="509" height="486" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Amongst the aspect related code, we have our ID property and our SomeMethod method. Notice that the getter and setter of ID are delegated to our aspect and so does our method. This is important to keep in mind because when implementing members, they must be marked as public inside of the aspect (because our target class has to access them). However, if you happen to forget, PostSharp will remind you with a compiler error&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.sharpcrafters.com/blog/image.axd?picture=image_21.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" src="http://www.sharpcrafters.com/blog/image.axd?picture=image_thumb_21.png" border="0" alt="image" width="628" height="40" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;But what happens if you don&amp;rsquo;t want the introduced members to be public in the target class? Have no fear, PostSharp thought of that too. Let&amp;rsquo;s have a look at the IntroduceMember attribute.&lt;/p&gt;
&lt;h3&gt;IntroduceMember attribute&lt;/h3&gt;
&lt;p&gt;By default, using IntroduceMember by itself will use public visibility and will cause compiler errors if a member with the same signature is already part of the class. We can control the behavior of how the member is implemented by changing the following parameters.&lt;/p&gt;
&lt;h4&gt;Visibility&lt;/h4&gt;
&lt;p&gt;By default, PostSharp will introduce the member to the target class with public visibility. We can specify one of the enumerations from PostSharp.Reflection.Visibility to control what visibility the member will have in the target class. Available values are&lt;/p&gt;
&lt;p&gt;&amp;middot; &lt;strong&gt;Public&lt;/strong&gt; (Default) &amp;ndash; Is publically available.&lt;/p&gt;
&lt;p&gt;&amp;middot; &lt;strong&gt;Family&lt;/strong&gt; &amp;ndash; Is available to the class and any derived classes. Same as protected.&lt;/p&gt;
&lt;p&gt;&amp;middot; &lt;strong&gt;Assembly&lt;/strong&gt; &amp;ndash; Is publicly available within the assembly. Same as internal.&lt;/p&gt;
&lt;p&gt;&amp;middot; &lt;strong&gt;FamilyOrAssembly&lt;/strong&gt; &amp;ndash; Is available to the class and any derived classes, but only within the assembly. Same as protected internal.&lt;/p&gt;
&lt;p&gt;&amp;middot; &lt;strong&gt;FamilyAndAssembly&lt;/strong&gt; &amp;ndash; Protected types inside the assembly. There is no C# equivalent.&lt;/p&gt;
&lt;p&gt;&amp;middot; &lt;strong&gt;Private&lt;/strong&gt; &amp;ndash; Only visible to the class.&lt;/p&gt;
&lt;h4&gt;OverrideAction&lt;/h4&gt;
&lt;p&gt;There is a chance that the target class already has a member with the same signature. By default, there will be a compiler error if this scenario is encountered. To change the behavior, we can provide one of the enumerations from PostSharp.Aspects.Advices.MemberOverrideAction.&lt;/p&gt;
&lt;p&gt;&amp;middot; &lt;strong&gt;Default&lt;/strong&gt; &amp;ndash; Fails with a compiler error.&lt;/p&gt;
&lt;p&gt;&amp;middot; &lt;strong&gt;Fail&lt;/strong&gt; &amp;ndash; Fails with a compiler error.&lt;/p&gt;
&lt;p&gt;&amp;middot; &lt;strong&gt;Ignore&lt;/strong&gt; &amp;ndash; Continues on, without trying to introduce the member.&lt;/p&gt;
&lt;p&gt;&amp;middot; &lt;strong&gt;OverrideOrFail&lt;/strong&gt; &amp;ndash; Tries to override the member with our own implementation. If the existing member is defined in a base class and is sealed or non-virtual, it will fail with a compiler error.&lt;/p&gt;
&lt;p&gt;&amp;middot; &lt;strong&gt;OverrideOrIgnore&lt;/strong&gt; &amp;ndash; Tries to override the member with our own implementation. If the existing member is defined in a base class and is sealed or non-virtual, it will ignore the member introduction and continue on.&lt;/p&gt;
&lt;h5&gt;IsVirtual&lt;/h5&gt;
&lt;p&gt;If you would like to introduced member to be virtual (overridable in derived classes) then you can set IsVirtual to true. The member signature in the base class will be marked as virtual.&lt;/p&gt;
&lt;h4&gt;CopyCustomAttributesAttribute&lt;/h4&gt;
&lt;p&gt;Sometimes members need to be decorated with attributes. An example of this would be decorating members of a DataContract with DataMember. However, when introducing members from an aspect, any attributes applied to the member in the aspect will not be introduced along with the member in the target. We can use CopyCustomAttributes attribute in addition to the IntroduceMember attribute to introduce the attributes along with the member. Let&amp;rsquo;s look at an example.&lt;/p&gt;
&lt;pre&gt;[Serializable]
public class IntroduceAspect : TypeLevelAspect
{
    [IntroduceMember]
    [DataMember(IsRequired=true)]
    public int ID { get; set; }
}

[IntroduceAspect]
[DataContract]
public class TargetClass
{
    [DataMember]
    public string FirstName { get; set; }
}&lt;/pre&gt;
&lt;p&gt;Our aspect is introducing a member, ID, which is decorated with DataMember. Let&amp;rsquo;s look at the result in ILSpy&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.sharpcrafters.com/blog/image.axd?picture=image_22.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" src="http://www.sharpcrafters.com/blog/image.axd?picture=image_thumb_22.png" border="0" alt="image" width="405" height="255" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The DataMember attribute is not present on ID. Let&amp;rsquo;s update the aspect to use CopyCustomAttributes.&lt;/p&gt;
&lt;pre&gt;[Serializable]
public class IntroduceAspect : TypeLevelAspect
{
    [IntroduceMember, CopyCustomAttributes(typeof(DataMemberAttribute), 
            OverrideAction = CustomAttributeOverrideAction.MergeReplaceProperty)]
    [DataMember(IsRequired=true)]
    public int ID { get; set; }

}&lt;/pre&gt;
&lt;p&gt;In the constructor for CopyCustomAttributes we pass in the base type for the desired attribute and then we set the override action with a value from the CustomAttributeOverrideAction enumeration. When we look at the end result in ILSpy, we see that the attribute was introduced along with the member.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.sharpcrafters.com/blog/image.axd?picture=image_23.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" src="http://www.sharpcrafters.com/blog/image.axd?picture=image_thumb_23.png" border="0" alt="image" width="512" height="293" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h5&gt;CustomAttributeOverrideAction&lt;/h5&gt;
&lt;p&gt;CustomAttributeOverrideAction is an enum that lets us tell PostSharp how to handle a situation when an attribute of the same type already exists on the target member.&lt;/p&gt;
&lt;p&gt;&amp;middot; &lt;strong&gt;Default&lt;/strong&gt; &amp;ndash; Fails with a compile time error.&lt;/p&gt;
&lt;p&gt;&amp;middot; &lt;strong&gt;Fail&lt;/strong&gt; &amp;ndash; Fails with a compile time error.&lt;/p&gt;
&lt;p&gt;&amp;middot; &lt;strong&gt;Ignore&lt;/strong&gt; &amp;ndash; Ignores the attribute introduction and does not generate an error.&lt;/p&gt;
&lt;p&gt;&amp;middot; &lt;strong&gt;Add&lt;/strong&gt; &amp;ndash; Adds the attribute as defined, even if it already exists on the target. This could cause duplicate attributes on the target.&lt;/p&gt;
&lt;p&gt;&amp;middot; &lt;strong&gt;MergeAddProperty&lt;/strong&gt; &amp;ndash; Combines the existing attribute with the attribute being introduced. Any properties defined by the existing attribute will remain. No override will occur. Any properties defined by the introduced attribute will be added to the existing attribute.&lt;/p&gt;
&lt;p&gt;&amp;middot; &lt;strong&gt;MergeReplaceProperty&lt;/strong&gt; &amp;ndash; Same as MergeAddProperty except that any properties defined by the existing attribute will overridden by the introduced attribute.&lt;/p&gt;
&lt;h3&gt;Interface Introduction&lt;/h3&gt;
&lt;p&gt;When introducing an interface via an aspect, the interface must be implemented on the aspect itself. The type will expose the interface at run time, but the aspect actually implements it. Let&amp;rsquo;s have a look at our interface:&lt;/p&gt;
&lt;pre&gt;public interface IFriendlyName
{
    string Name { get; set; }
    void PrintName();
}&lt;/pre&gt;
&lt;p&gt;And now our aspect:&lt;/p&gt;
&lt;pre&gt;[Serializable]
[IntroduceInterface(typeof(IFriendlyName))]
public class IntroduceAspect : InstanceLevelAspect, IFriendlyName
{
    #region IFriendlyName Members

    public string Name { get; set; }
        
    public void PrintName()
    {
        Console.WriteLine(this.Name);
    }

    #endregion
}&lt;/pre&gt;
&lt;p&gt;Our test class remains the same, empty&lt;/p&gt;
&lt;pre&gt;[IntroduceAspect]
public class TestClass
{

}&lt;/pre&gt;
&lt;p&gt;When we look at the compiled result we see our interface has been implemented&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.sharpcrafters.com/blog/image.axd?picture=image_24.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" src="http://www.sharpcrafters.com/blog/image.axd?picture=image_thumb_24.png" border="0" alt="image" width="628" height="405" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Notice that we didn&amp;rsquo;t use the IntroduceMember attribute on the interface members. Also notice that the resulting implementations of the interface members are private. To make the interface members public we have to apply the IntroduceMember attribute to the members&lt;/p&gt;
&lt;pre&gt;[Serializable]
[IntroduceInterface(typeof(IFriendlyName))]
public class IntroduceAspect : InstanceLevelAspect, IFriendlyName
{
    #region IFriendlyName Members

    [IntroduceMember]
    public string Name { get; set; }

    [IntroduceMember]
    public void PrintName()
    {
        Console.WriteLine(this.Name);
    }

    #endregion
}&lt;/pre&gt;
&lt;p&gt;And now the compiled result shows two implementations of our members&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.sharpcrafters.com/blog/image.axd?picture=image_25.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" src="http://www.sharpcrafters.com/blog/image.axd?picture=image_thumb_25.png" border="0" alt="image" width="628" height="405" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Looking at the PrintName method, the explicit interface implementation is private, but we&amp;rsquo;ve introduced a public version which the interface method calls.&lt;/p&gt;
&lt;h3&gt;IntroduceInterface attribute&lt;/h3&gt;
&lt;p&gt;To tell PostSharp that we want to introduce an interface, we decorate the aspect with the IntroduceInterface attribute. To tell PostSharp which interface to implement, we pass in a type using typeof(IFriendlyName). Just like the IntroduceMember attribute, there are parameters to control the behavior of the introduction.&lt;/p&gt;
&lt;p&gt;&amp;middot; OverrideAction &amp;ndash; Exactly the same as IntroduceMember. Determines what to do when the target already implements the interface. Default is to fail with a compiler error.&lt;/p&gt;
&lt;p&gt;&amp;middot; IsProtected &amp;ndash; If set to true, the interface is not directly implemented by the type. Instead, the type exposes the interface through the IProtectedInterface&amp;lt;T&amp;gt;. Since protected interfaces are considered obsolete, you should leave this as false (default).&lt;/p&gt;
&lt;p&gt;&amp;middot; AncestorOverrideAction &amp;ndash; Defines the behavior of the introduction when and ancestor of the interface is already applied to the target class. See example below. Available enumerations in the PostSharp.Aspects.Advices.InterfaceOverrideAction are Default (Fail), Fail and Ignore.&lt;/p&gt;
&lt;h3&gt;Extended Example&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s finish up with a bit more in-depth example using some of the behavior parameters.&lt;/p&gt;
&lt;pre&gt;public interface IIdentifiable
{
    Guid ID { get; set; }
}

public interface IFriendlyName : IIdentifiable
{
    string Name { get; set; }
    void PrintName();
}

[IntroduceAspect]
public class TargetClass : IIdentifiable
{
    #region IFriendlyNameBase Members

    public Guid ID { get; set; }   

    #endregion

    string Name { get; set; }

    public void PrintName()
    {
        throw new NotImplementedException();
    }
}

[Serializable]
[IntroduceInterface(typeof(IFriendlyName), &lt;br /&gt;                   AncestorOverrideAction=InterfaceOverrideAction.Ignore)]
public class IntroduceAspect : InstanceLevelAspect, IFriendlyName
{
    #region IFriendlyName Members
    [IntroduceMember(OverrideAction=MemberOverrideAction.Ignore)]
    public Guid ID { get; set; }   

    [IntroduceMember(OverrideAction=MemberOverrideAction.Ignore)]
    public string Name { get; set; }

    [IntroduceMember(OverrideAction=MemberOverrideAction.OverrideOrFail)]
    public void PrintName()
    {
        Console.WriteLine(this.Name);
    }

    #endregion
}&lt;/pre&gt;
&lt;p&gt;We define two interfaces. IFriendlyName implements IIdentifiable. Our test class implements IIdentifiable and also has a PrintName method which throws an exception. Our aspect specifies the introduction of IFriendlyName and also implements the required interface members. We specify that we should ignore any implementation of an ancestor (IIdentifiable) of the introduced interface (IFriendlyName). We also specify that we want to ignore the member introduction on the two properties if they exist in the target class. We mark PrintName with the OverrideOrFail because we want to force our own implementation of the PrintName method. The end result looks like this&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.sharpcrafters.com/blog/image.axd?picture=image_26.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" src="http://www.sharpcrafters.com/blog/image.axd?picture=image_thumb_26.png" border="0" alt="image" width="628" height="405" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;First take a look at the PrintName method. Instead of the original method body, which threw an exception, we see that there is a call to our aspect which invokes our implementation of that method.&lt;/p&gt;
&lt;p&gt;Next we see that both interfaces are implemented, but we only have get/set methods for the Name property, not the ID property. This is because PostSharp ignored the implementation of IIdentifiable since it was already implemented on the target class. If we remove InterfaceOverride.Ignore from the IntroduceInterface attribute, we would get a compiler error.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.sharpcrafters.com/blog/image.axd?picture=image_27.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" src="http://www.sharpcrafters.com/blog/image.axd?picture=image_thumb_27.png" border="0" alt="image" width="628" height="52" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If we removed the implementation of IIdentifiable from our test class, we would see get/set methods for ID in the compiled results.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.sharpcrafters.com/blog/image.axd?picture=image_28.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" src="http://www.sharpcrafters.com/blog/image.axd?picture=image_thumb_28.png" border="0" alt="image" width="628" height="405" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Today we covered some good ground on introducing members and interfaces along with some of the nuances that you have to be aware of. Tomorrow we&amp;rsquo;ll continue with importing members and accessing introduced members at compile time.&lt;/p&gt;
&lt;div style="padding-bottom: 10px; padding-left: 0px; padding-right: 0px; padding-top: 10px"&gt;&lt;a href="http://www.sharpcrafters.com/blog/image.axd?picture=self573_thumb%5B1%5D_3.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 5px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="self573_thumb[1]" src="http://www.sharpcrafters.com/blog/image.axd?picture=self573_thumb%5B1%5D_thumb_3.jpg" border="0" alt="self573_thumb[1]" width="66" height="66" align="left" /&gt;&lt;/a&gt;Dustin Davis Davis is an enterprise solutions developer and regularly speaks at user groups and code camps. He can be followed on Twitter &lt;a href="http://twitter.com/#!/PrgrmrsUnlmtd"&gt;@PrgrmrsUnlmtd&lt;/a&gt; or his blog &lt;a href="http://www.programmers-unlimited.com"&gt;Programmers-Unlimited.com&lt;/a&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=PwTMC1hB2Ho:QfvNWS7MvYw:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=PwTMC1hB2Ho:QfvNWS7MvYw:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=PwTMC1hB2Ho:QfvNWS7MvYw:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=PwTMC1hB2Ho:QfvNWS7MvYw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=PwTMC1hB2Ho:QfvNWS7MvYw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=PwTMC1hB2Ho:QfvNWS7MvYw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=PwTMC1hB2Ho:QfvNWS7MvYw:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=PwTMC1hB2Ho:QfvNWS7MvYw:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=PwTMC1hB2Ho:QfvNWS7MvYw:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=PwTMC1hB2Ho:QfvNWS7MvYw:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=PwTMC1hB2Ho:QfvNWS7MvYw:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=PwTMC1hB2Ho:QfvNWS7MvYw:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/postsharp/~4/PwTMC1hB2Ho" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Dustin Davis</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/post.aspx?id=ad025148-6d25-432d-bf1c-567c8186e32c</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">2</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.sharpcrafters.com/blog/trackback.axd?id=ad025148-6d25-432d-bf1c-567c8186e32c</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/post/PostSharp-Principals-Day-14-e28093-Introducing-members-and-interfaces-Part-1.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/syndication.axd?post=ad025148-6d25-432d-bf1c-567c8186e32c</wfw:commentRss><feedburner:origLink>http://www.sharpcrafters.com/blog/post.aspx?id=ad025148-6d25-432d-bf1c-567c8186e32c</feedburner:origLink></item><item><title>Announcing PostSharp 2.1 CTP 3</title><link>http://feedproxy.google.com/~r/postsharp/~3/Gvyfjp420AI/post.aspx</link><category>Annoucement</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Gael Fraiteur</dc:creator><pubDate>Thu, 14 Jul 2011 03:31:00 PDT</pubDate><guid isPermaLink="false">http://www.sharpcrafters.com/blog/post.aspx?id=959e3542-00b3-4a3e-9d20-16e751b4f346</guid><description>&lt;p&gt;I'm pleased to announce that the third and final Community Technical Preview of PostSharp 2.1 is now available for download on &lt;a href="http://www.sharpcrafters.com/downloads/postsharp-2.1/ctp-3" target="_blank"&gt;our website&lt;/a&gt; and as a &lt;a href="http://www.nuget.org/List/Packages/PostSharp" target="_blank"&gt;NuGet package&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The new CTP is principally a stabilization release, with a large number of bug fixes (including all hot fixes from the 2.0 branch) and some corrections in the new API design. This CTP is more stable than the latest builds on the 2.0 branch, but this has of course to be validated by the community.&lt;/p&gt;  &lt;h2&gt;What’s New in PostSharp 2.1 CTP 3&lt;/h2&gt;  &lt;ul&gt;   &lt;li&gt;A streamlined experience for first-time users, including a redesigned &lt;i&gt;PostSharp HQ&lt;/i&gt; application and new &lt;i&gt;Learn PostSharp&lt;/i&gt; tool window in Visual Studio. &lt;/li&gt;    &lt;li&gt;PostSharp does not enter the evaluation mode automatically. Instead, a dialog box will ask you to explicitly enter the evaluation mode. This adds a little friction for those evaluating PostSharp but should help to clarify any licensing questions. &lt;/li&gt;    &lt;li&gt;Complete class reference documentation (the conceptual documentation is still not updated). &lt;/li&gt;    &lt;li&gt;Support for Windows Phone 7.1 Beta. &lt;/li&gt;    &lt;li&gt;Support for Silverlight and Windows Phone in the NuGet package. &lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;What’s New in PostSharp 2.1 CTP 2&lt;/h2&gt;  &lt;ul&gt;   &lt;li&gt;Architecture constraints. &lt;/li&gt;    &lt;li&gt;Extended build-time reflection API. &lt;/li&gt;    &lt;li&gt;Support for obfuscation. &lt;/li&gt;    &lt;li&gt;Support for Silverlight 5. &lt;/li&gt;    &lt;li&gt;License server.&lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;What's New in PostSharp 2.1 CTP 1&lt;/h2&gt;  &lt;ul&gt;   &lt;li&gt;Improvements in build-time performance. &lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;What’s Next?&lt;/h2&gt;  &lt;p&gt;Now that the design is nearly finalized, we should finally blog about and document new features. The release candidate will be published as soon as the documentation is complete (the current release has been tested to release candidate-level quality).&lt;/p&gt;  &lt;h2&gt;Update Today&lt;/h2&gt;  &lt;p&gt;If your application is not going to production in the next few months, now is a great time to download PostSharp 2.1 and to upgrade your current application in a feature branch. Doing so will help us to validate the new version and move the final release date forward. Please report all issues on the support forum. Thanks!&lt;/p&gt;  &lt;p&gt;Happy PostSharping!&lt;/p&gt;  &lt;p&gt;-gael&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=Gvyfjp420AI:RSJVHPv99A4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=Gvyfjp420AI:RSJVHPv99A4:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=Gvyfjp420AI:RSJVHPv99A4:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=Gvyfjp420AI:RSJVHPv99A4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=Gvyfjp420AI:RSJVHPv99A4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=Gvyfjp420AI:RSJVHPv99A4:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=Gvyfjp420AI:RSJVHPv99A4:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=Gvyfjp420AI:RSJVHPv99A4:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=Gvyfjp420AI:RSJVHPv99A4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=Gvyfjp420AI:RSJVHPv99A4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=Gvyfjp420AI:RSJVHPv99A4:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=Gvyfjp420AI:RSJVHPv99A4:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/postsharp/~4/Gvyfjp420AI" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Gael Fraiteur</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/post.aspx?id=959e3542-00b3-4a3e-9d20-16e751b4f346</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">4</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.sharpcrafters.com/blog/trackback.axd?id=959e3542-00b3-4a3e-9d20-16e751b4f346</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/post/Announcing-PostSharp-21-CTP-3.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/syndication.axd?post=959e3542-00b3-4a3e-9d20-16e751b4f346</wfw:commentRss><feedburner:origLink>http://www.sharpcrafters.com/blog/post.aspx?id=959e3542-00b3-4a3e-9d20-16e751b4f346</feedburner:origLink></item><item><title>PostSharp Principles: Day 13 – Aspect Providers, Part 2</title><link>http://feedproxy.google.com/~r/postsharp/~3/R1J9XPCcoew/post.aspx</link><category>Tutorial</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Dustin Davis</dc:creator><pubDate>Wed, 13 Jul 2011 08:24:00 PDT</pubDate><guid isPermaLink="false">http://www.sharpcrafters.com/blog/post.aspx?id=39920baa-d980-474f-91e4-15be8016916a</guid><description>&lt;p&gt;When it comes to building complex aspects to solve a specific problem or implement a pattern, the base classes such as OnMethodBoundaryAspect and LocationInterceptionAspect aren’t always up-to the job. We covered the IAspectProvider yesterday, which allows us to dynamically tell PostSharp which aspects to apply to a target at compile time. Today we’re going to build complex aspects that encapsulate multiple transformations in a single aspect. &lt;/p&gt;  &lt;h3&gt;Advices and Pointcuts&lt;/h3&gt;  &lt;p&gt;Before we continue, we should cover some vocabulary. We’ve avoided the use of these terms until now to avoid any confusion.&lt;/p&gt;  &lt;p&gt;· Advice – “An advice is anything that adds a behavior or a structural element to an element of code. For instance, introducing a method into a class, intercepting a property setter, or catching exceptions, are advices.” &lt;/p&gt;  &lt;p&gt;· Pointcut – “A pointcut is a function returning a set of elements of code to which advices apply. For instance, a function returning the set of properties annotated with the custom attribute DataMember is a pointcut.”&lt;/p&gt;  &lt;p&gt;When we override the OnEntry method when building an aspect based on OnMethodBoundaryAspect, we’re providing the advice to implement. By default the pointcut would be all methods in a class, if the class was decorated with our aspect based on the OnMethodBoundaryAspect base class. &lt;/p&gt;  &lt;p&gt;PostSharp provides us with a set of attributes for declaring advice and pointcuts in any combination under a single aspect. Let’s have a look at an example to give a better picture&lt;/p&gt;  &lt;pre&gt;[Serializable]
public class ComplexAspect : TypeLevelAspect
{
    private int MethodCounter = 0; //Shared between all advices

    [OnMethodInvokeAdvice, MulticastPointcut(Targets =
                        MulticastTargets.Method, MemberName = &amp;quot;DoSomethingElse&amp;quot;)]
    public void OnInvoke(MethodInterceptionArgs args)
    {
        Console.WriteLine(&amp;quot;Before method {0}. MethodCounter = {1}&amp;quot;, &lt;br /&gt;                                              args.Method.Name, this.MethodCounter);
        args.Proceed();
        Console.WriteLine(&amp;quot;After method {0}. MethodCounter = {1}&amp;quot;, &lt;br /&gt;                                              args.Method.Name, this.MethodCounter);
    }

    [OnMethodEntryAdvice, MulticastPointcut(Targets = MulticastTargets.Method)]
    public void OnEntry(MethodExecutionArgs args)
    {
        MethodCounter++;
        Console.WriteLine(&amp;quot;Entering {0}. MethodCounter = {1}&amp;quot;, &lt;br /&gt;                                               args.Method.Name, this.MethodCounter);
    }

    [OnMethodExitAdvice(Master = &amp;quot;OnEntry&amp;quot;)]
    public void OnExit(MethodExecutionArgs args)
    {
        Console.WriteLine(&amp;quot;Exiting {0}. MethodCounter = {1}&amp;quot;, &lt;br /&gt;                                               args.Method.Name, this.MethodCounter);
    }

    [OnLocationSetValueAdvice, MulticastPointcut(Targets = MulticastTargets.Property)]
    public void OnPropertySet(LocationInterceptionArgs args)
    {
        MethodCounter++;
        Console.WriteLine(&amp;quot;Setting property: {0} = {1}. MethodCounter = {2}&amp;quot;, &lt;br /&gt;                                     args.LocationName, args.Value, this.MethodCounter);
    }
}&lt;/pre&gt;

&lt;p&gt;Our aspect derives from TypeLevelAspect, not one of the base classes we’ve been using. We have four methods in our aspect and each method is decorated with an advice attribute along with a pointcut attribute. &lt;/p&gt;

&lt;p&gt;The OnEntry method is decorated with the OnMethodEntryAdvice attribute which has the same semantics of overriding the OnEntry method in an OnMethodBoundaryAspect. The MulticastPointcut attribute is used and passed the MulticastTargets.Method flag to let PostSharp know that we want to apply this advice to methods in general.&lt;/p&gt;

&lt;p&gt;Because we’re using TypeLevelAspect instead of OnMethodBoundaryAspect, we are able to share state between advices. When using OnMethodBoundaryAspect, an instance of our aspect is created for each target. For example, Method1 would have its own copy of our aspect and Method2 would have its own copy. Using TypeLevelAspect to implement our advices changes that behavior; we have a single instance of our aspect that is used for each target which means that the advices get to share state. We’re going to demonstrate this using the MethodCounter field to increment on each method entry and display its value throughout the other advices.&lt;/p&gt;

&lt;p&gt;Notice the OnExit advice isn’t specifying a pointcut, but instead is passing in a value to the Master parameter on the OnMethodExitAdvice attribute. We’re defining the master advice method, which means we’re grouping the advices on the same “layer”. OnExit will be a slave method and will inherit the pointcut selectors from OnEntry since only master advice methods can define pointcuts. We only do this for advices of the same category of transformations. For example, you wouldn’t define OnEntry as the master advice method for OnPropertySet because they perform different transformations. We’ll cover grouping on another day. &lt;/p&gt;

&lt;p&gt;The other methods in our aspect are the same, just using different advices. The OnInvoke method however has a different pointcut setup. We add an additional parameter, MemberName, giving it a value of “DoSomethingElse” which tells PostSharp to only apply the advice to methods matching “DoSomethingElse”. &lt;/p&gt;

&lt;p&gt;Let’s run our example code and look at the result&lt;/p&gt;

&lt;pre&gt;class Program
{
    static void Main(string[] args)
    {
        ExampleClass ec = new ExampleClass();
        ec.DoSomething();
        ec.DoSomethingElse();
        ec.FirstName = &amp;quot;John&amp;quot;;
        ec.LastName = &amp;quot;Smith&amp;quot;;

        Console.ReadKey();
    }
}

[ComplexAspect]
public class ExampleClass
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public void DoSomething()
    {
        Console.WriteLine(&amp;quot;Doing something&amp;quot;);            
    }

    public void DoSomethingElse()
    {
        Console.WriteLine(&amp;quot;Doing something else&amp;quot;);
    }

}&lt;/pre&gt;
&lt;br /&gt;&amp;nbsp;
&lt;pre&gt;Entering DoSomething. MethodCounter = 1
Doing something
Exiting DoSomething. MethodCounter = 1
Before method DoSomethingElse. MethodCounter = 1
Entering DoSomethingElse. MethodCounter = 2
Doing something else
Exiting DoSomethingElse. MethodCounter = 2
After method DoSomethingElse. MethodCounter = 2
Entering set_FirstName. MethodCounter = 3
Setting property: FirstName = John. MethodCounter = 4
Exiting set_FirstName. MethodCounter = 4
Entering set_LastName. MethodCounter = 5
Setting property: LastName = Smith. MethodCounter = 6
Exiting set_LastName. MethodCounter = 6&lt;/pre&gt;

&lt;p&gt;
  &lt;br /&gt;In a single aspect, we have implemented advice and pointcuts that we normally would have written three different aspects using the base classes. In addition, we were able to share state between those advices. Examine the output of the MethodCounter. It’s incrementing as we continue along with the execution. If we had three individual aspects the provided equivalent advices, the output would look more like&lt;/p&gt;

&lt;pre&gt;Entering DoSomething. MethodCounter = 1
Doing something
Exiting DoSomething. MethodCounter = 1
Before method DoSomethingElse. MethodCounter = 0
Entering DoSomethingElse. MethodCounter = 1
Doing something else
Exiting DoSomethingElse. MethodCounter = 1
After method DoSomethingElse. MethodCounter = 0
Entering set_FirstName. MethodCounter = 1
Setting property: FirstName = John. MethodCounter = 1
Exiting set_FirstName. MethodCounter = 1
Entering set_LastName. MethodCounter = 1
Setting property: LastName = Smith. MethodCounter = 1
Exiting set_LastName. MethodCounter = 1&lt;/pre&gt;

&lt;h3&gt;Advices&lt;/h3&gt;

&lt;p&gt;There are a few advice attributes that you can use. Each advice attribute has a corresponding simple aspect base class and behaves in the same way. 
  &lt;table border="0" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;
      &lt;tr&gt;
        &lt;td valign="top" width="217"&gt;
          &lt;p&gt;&lt;b&gt;OnMethodEntryAdvice&lt;/b&gt;&lt;/p&gt;

          &lt;p&gt;&lt;b&gt;OnMethodSuccessAdvice&lt;/b&gt;&lt;/p&gt;

          &lt;p&gt;&lt;b&gt;OnMethodExceptionAdvice&lt;/b&gt;&lt;/p&gt;

          &lt;p&gt;&lt;b&gt;OnMethodExitAdvice 
              &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
        &lt;/td&gt;

        &lt;td valign="top" width="421"&gt;
          &lt;p&gt;These advices are the equivalent to the advices in the OnMethodBoundaryAspect base class&lt;/p&gt;
        &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="top" width="217"&gt;
          &lt;p&gt;&lt;b&gt;OnMethodInvokeAdvice 
              &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
        &lt;/td&gt;

        &lt;td valign="top" width="421"&gt;
          &lt;p&gt;These advices are the equivalent to the advices in the MethodInterceptionAspect base class&lt;/p&gt;
        &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="top" width="217"&gt;
          &lt;p&gt;&lt;b&gt;OnLocationGetValueAdvice&lt;/b&gt;&lt;/p&gt;

          &lt;p&gt;&lt;b&gt;OnLocationSetValueAdvice 
              &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
        &lt;/td&gt;

        &lt;td valign="top" width="421"&gt;
          &lt;p&gt;These advices are the equivalent to the advices in the LocationInterceptionAspect base class&lt;/p&gt;
        &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="top" width="217"&gt;
          &lt;p&gt;&lt;b&gt;OnEventAddHandlerAdvice&lt;/b&gt;&lt;/p&gt;

          &lt;p&gt;&lt;b&gt;OnEventRemoveHandlerAdvice&lt;/b&gt;&lt;/p&gt;

          &lt;p&gt;&lt;b&gt;OnEventInvokeHandlerAdvice 
              &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
        &lt;/td&gt;

        &lt;td valign="top" width="421"&gt;
          &lt;p&gt;These advices are the equivalent to the advices in the EventInterceptionAspect base class&lt;/p&gt;
        &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="top" width="217"&gt;
          &lt;p&gt;&lt;b&gt;IntroduceMember&lt;/b&gt;&lt;/p&gt;
        &lt;/td&gt;

        &lt;td valign="top" width="421"&gt;
          &lt;p&gt;Introduce a method, property or event to the target class.&lt;/p&gt;
        &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="top" width="217"&gt;
          &lt;p&gt;&lt;b&gt;IntroduceInterface&lt;/b&gt;&lt;/p&gt;
        &lt;/td&gt;

        &lt;td valign="top" width="421"&gt;
          &lt;p&gt;Introduce a method to the target class.&lt;a name="_GoBack"&gt;&lt;/a&gt;&lt;/p&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;&lt;/table&gt;
&lt;/p&gt;

&lt;p&gt;When applying advice to a method, the method must be public and have the same signature as the corresponding base class advice signature. For example, in order to apply OnLocationGetValueAdvice on a method, the method must be public and have a single LocationInterceptionArgs parameter with no return value (void). &lt;/p&gt;

&lt;h3&gt;Pointcuts&lt;/h3&gt;

&lt;p&gt;A pointcut has to be defined in order to tell PostSharp where to apply the advice. You can think of pointcuts as expressions that return a set of elements of code. These elements of code must be compatible with the type of advice (for instance, do not try to add an OnLocationGetValue advice to a field). Remember that you can only add advices to code that belong to the target of the aspect. So if the aspect has been applied to a type, you can only add advices to members of this type, or to the type itself. 
  &lt;table border="0" cellspacing="0" cellpadding="0"&gt;&lt;tbody&gt;
      &lt;tr&gt;
        &lt;td valign="top" width="193"&gt;
          &lt;p&gt;&lt;b&gt;MulticastPointcut&lt;/b&gt;&lt;/p&gt;
        &lt;/td&gt;

        &lt;td valign="top" width="445"&gt;
          &lt;p&gt;A declarative pointcut that works similarly to MulticastAttribute. &lt;/p&gt;
        &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="top" width="193"&gt;
          &lt;p&gt;&lt;b&gt;MethodPointcut&lt;/b&gt;&lt;/p&gt;
        &lt;/td&gt;

        &lt;td valign="top" width="445"&gt;
          &lt;p&gt;An imperative pointcut: the pointcut is a method that returns an enumeration of elements of code. The method can be implemented in C#, for instance using Linq.&lt;/p&gt;
        &lt;/td&gt;
      &lt;/tr&gt;

      &lt;tr&gt;
        &lt;td valign="top" width="193"&gt;
          &lt;p&gt;&lt;b&gt;SelfPointcut&lt;/b&gt;&lt;/p&gt;
        &lt;/td&gt;

        &lt;td valign="top" width="445"&gt;
          &lt;p&gt;A pointcut that evaluates to the target of the aspect.&lt;/p&gt;
        &lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;&lt;/table&gt;
&lt;/p&gt;

&lt;h4&gt;MulticastPointcut&lt;/h4&gt;

&lt;h6&gt;MemberName&lt;/h6&gt;

&lt;p&gt;MemberName takes an expression (static name, wildcard or regular expression) to specify targets.&lt;/p&gt;

&lt;h6&gt;Targets&lt;/h6&gt;

&lt;p&gt;Targets can be set to a combination of MulticastTargets flags. For example, MulticastTargets.Method | MulticastTargets.Property to specify the targets will be methods and properties. &lt;/p&gt;

&lt;h6&gt;Attributes&lt;/h6&gt;

&lt;p&gt;Attributes is how we define the scope and visibility of the intended targets and can be set to a combination of MulticastAttributes flags. For example, we can target members that are private and static by using MulticastAttributes.Private | MulticastAttributes.Static.&lt;/p&gt;

&lt;h3&gt;MethodPointcut&lt;/h3&gt;

&lt;p&gt;MethodPointcut allows us to pass in the name of a method that PostSharp can use to get a list of targets. Let’s look at an example&lt;/p&gt;

&lt;pre&gt;[Serializable]
public class ExampleAspect : TypeLevelAspect
{
    public IEnumerable&lt;methodinfo&gt; FindTargetMethods(Type target)
    {
        IEnumerable&lt;methodinfo&gt; targets = target.GetMethods()
                         .Where(c =&amp;gt; c.Name.Contains(&amp;quot;Something&amp;quot;));
        return targets;
    }

    [OnMethodEntryAdvice, MethodPointcut(&amp;quot;FindTargetMethods&amp;quot;)]
    public void OnEntry(MethodExecutionArgs args)
    {
        Console.WriteLine(&amp;quot;Entering method: &amp;quot; + args.Method.Name);
    }

}&lt;/pre&gt;

&lt;p&gt;Our aspect has only one advice that we want to implement, OnMethodEntryAdvice. We use the MethodPointcut attribute and pass it “FindTargetMethods” which is the name of the method we’ve setup to determine which methods will be targets. The method that is going to return the targets has to have a specific signature. PostSharp documentation defines this signature as&lt;/p&gt;

&lt;pre&gt;IEnumerable&lt;advicetargettype&gt; SelectCodeElements(AspectTargetType target)&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;AdviceTargetType&lt;/b&gt; will be replaced with either object or a reflection type representing the targets of the advice. For example, MethodInfo when the advice targets are methods and PropertyInfo when the targets are Properties.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;AspectTargetType&lt;/b&gt; will be replaced with either object or a reflection type corresponding to the targets of the aspect. For example, Type for AssemblyLevelAspect, TypeLevelAspect, InstanceLevelAspect and MethodInfo for MethodLevelAspect.&lt;/p&gt;

&lt;p&gt;If the signature is not valid for the type of aspect then PostSharp will produce a compiler error. When we apply the aspect to our example class and run the application, we see that PostSharp has applied the advice to both of the class methods.&lt;/p&gt;

&lt;pre&gt;public class Program
{
    static void Main(string[] args)
    {
        ExampleClass ec = new ExampleClass();
        ec.DoSomething();
        ec.DoSomething1();

        Console.ReadKey();
    }
}

[ExampleAspect]
public class ExampleClass
{
    public int ID { get; set; }
    public string First { get; set; }
    public string Last { get; set; }

    public void DoSomething()
    {
        this.First = &amp;quot;John&amp;quot;;
        this.Last = &amp;quot;Smith&amp;quot;;
    }

    public void DoSomething1()
    {
        Console.WriteLine(&amp;quot;Did something&amp;quot;);
    }
}&lt;/pre&gt;

&lt;p&gt;The output is&lt;/p&gt;

&lt;pre&gt;Entering method: DoSomething
Entering method: DoSomething1
Did something&lt;/pre&gt;

&lt;h3&gt;
  &lt;br /&gt;SelfPointcut&lt;/h3&gt;

&lt;p&gt;There is a special attribute that you can use instead of MulticastPointcut, the SelfPointcut attribute. SelfPointcut tells PostSharp to select the exact aspect target. For example, if we have the following aspect&lt;/p&gt;

&lt;pre&gt;[Serializable]
public class ExampleAspect: MethodLevelAspect
{
    [OnMethodEntryAdvice, SelfPointcut]
    public void OnEntry(MethodExecutionArgs args)
    {
        Console.WriteLine(&amp;quot;Entering &amp;quot; + args.Method.Name);
    }

}&lt;/pre&gt;

&lt;p&gt;When applied to a method directly, the SelfPointcut will use that exact method as the target. If applied to a class, all methods in the class will get the advice because all of the methods would be the intended target. If the aspect was applied at the assembly level with specific targets configured, then PostSharp will use those exact targets. SelfPointcut is a way to defer the selection of pointcuts to a higher mechanism. &lt;/p&gt;

&lt;h3&gt;Benefits over base classes&lt;/h3&gt;

&lt;p&gt;Base classes encapsulate a single transformation, which means if you want to apply multiple transformations, you would need to build just as many aspects. For example, if you wanted to marshal a method invocation to a different thread and log exceptions that occur in that method, you would need to build two independent aspects and apply both to the target.&lt;/p&gt;

&lt;p&gt;Sharing state between advices in multiple independent aspects requires convoluted mechanics. Building complex aspects using advices and pointcuts provides the benefit of sharing state between advices.&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;By now you should have a clear understanding of how to build complex aspects using the tools provided by PostSharp. The term “complex” shouldn’t be a deterrent because over the last two days we’ve seen just how easy it is to build aspects. &lt;/p&gt;
&lt;div style="padding-bottom: 10px; padding-left: 0px; padding-right: 0px; padding-top: 10px"&gt;&lt;a href="http://www.sharpcrafters.com/blog/image.axd?picture=self573_thumb%5B1%5D_3.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px 5px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="self573_thumb[1]" border="0" alt="self573_thumb[1]" align="left" src="http://www.sharpcrafters.com/blog/image.axd?picture=self573_thumb%5B1%5D_thumb_3.jpg" width="66" height="66" /&gt;&lt;/a&gt;Dustin Davis Davis is an enterprise solutions developer and regularly speaks at user groups and code camps. He can be followed on Twitter &lt;a href="http://twitter.com/#!/PrgrmrsUnlmtd"&gt;@PrgrmrsUnlmtd&lt;/a&gt; or his blog &lt;a href="http://www.programmers-unlimited.com"&gt;Programmers-Unlimited.com&lt;/a&gt; &lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=R1J9XPCcoew:FfG8FxWnSwQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=R1J9XPCcoew:FfG8FxWnSwQ:63t7Ie-LG7Y"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=63t7Ie-LG7Y" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=R1J9XPCcoew:FfG8FxWnSwQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=R1J9XPCcoew:FfG8FxWnSwQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=R1J9XPCcoew:FfG8FxWnSwQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=R1J9XPCcoew:FfG8FxWnSwQ:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=R1J9XPCcoew:FfG8FxWnSwQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=R1J9XPCcoew:FfG8FxWnSwQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=R1J9XPCcoew:FfG8FxWnSwQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?i=R1J9XPCcoew:FfG8FxWnSwQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=R1J9XPCcoew:FfG8FxWnSwQ:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/postsharp?a=R1J9XPCcoew:FfG8FxWnSwQ:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/postsharp?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/postsharp/~4/R1J9XPCcoew" height="1" width="1"/&gt;</description><dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/">Dustin Davis</dc:publisher><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/pingback.axd</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://www.sharpcrafters.com/blog/post.aspx?id=39920baa-d980-474f-91e4-15be8016916a</pingback:target><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">1</slash:comments><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://www.sharpcrafters.com/blog/trackback.axd?id=39920baa-d980-474f-91e4-15be8016916a</trackback:ping><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/post/PostSharp-Principals-Day-13-e28093-Aspect-Providers-e28093-Part-2.aspx#comment</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.sharpcrafters.com/blog/syndication.axd?post=39920baa-d980-474f-91e4-15be8016916a</wfw:commentRss><feedburner:origLink>http://www.sharpcrafters.com/blog/post.aspx?id=39920baa-d980-474f-91e4-15be8016916a</feedburner:origLink></item></channel></rss>

