Fixing Attribute Interception Dependencies in Unity

In keeping with Onion Architecture and hexagonal architecture, core application code should not depend on infrastructure; it should be the other way around.  This is particularly true for the infrastructure of an IOC container – such as Unity.

Unfortunately, Unity’s attribute-based AOP policy interception violates this rule.  This post applies to the HandlerAttribute of both Unity 2.X and 3.0.

Some Context

Unity’s interception has dual API’s.  One is “behavior” based; a newer and more simplistic approach. Assuming I have an ITenantStore business interface, configuring behavior-based interception for custom logging and caching might look like this:

The other API for Unity interception is “policy” based, which is powerful and has its origins in EntLib’s object-builder code base.  Again with our ITenantStore business interface, policy-based configuration might look like this:

Clearly the policy-based approach is enabled by the behavior-based approach. And once enabled, two features become available: an AOP rule matching API and an attribute-driven AOP mechanism.

The attribute mechanism centers on custom classes that implement Unity’s abstract HandlerAttribute class (e.g. LoggingCallHandlerAttribute or CachingCallHandlerAttribute).  This allows business classes to designate aspects declaratively:

These HandlerAttribute derived attributes have the distinct ability to carry state that can be passed into the ICallHandler that is subsequently created. This is in contrast to the CustomAttributeMatchingRule, which also allows attribute driven AOP but cannot transmit state. But if the HandlerAttribute statefull construction of an ICallHandler is what you need, then there is a problem.

The Problem

Since the abstract HandlerAttribute is defined in a Unity assembly, it means any application business class carrying the annotation(s) will force the enclosing application business assembly to take a dependency on Unity.  That is, before an annotation was added the business project’s Visual Studio assembly references may have been:

  • Microsoft.CSharp
  • System
  • System.Core
  • System.Data
  • System.Data.DataSetExtensions
  • System.Xml
  • System.Xml.Linq

After a Unity AOP attribute annotation was added, the Visual Studio assembly references then become:

  • Microsoft.CSharp
  • Microsoft.Practices.ServiceLocation
  • Microsoft.Practices.Unity
  • Microsoft.Practices.Unity.Configuration
  • Microsoft.Practices.Unity.Interception
  • Microsoft.Practices.Unity.Interception.Configuration
  • System
  • System.Core
  • System.Data
  • System.Data.DataSetExtensions
  • System.Xml
  • System.Xml.Linq

Technically, not all of the above Unity dependencies are necessary.  But the most common way to add Unity dependencies is with NuGet, and the NuGet package for Unity will assign all the above dependencies.

The more dependencies and coupling, the more cumbersome it is to do testing, refactoring, and maintenance.

The Solution

Fixing the attribute-driven Unity AOP implies inspecting how its existing attribute-driven approach is implemented.

After a bit of reflectoring around Unity’s innards, it becomes evident that the PolicyInjectionBehavior is itself constructor-injected by Unity with an array of InjectionPolicy instances.  One of those policies – AttributeDrivenPolicy – is registered in the Initialize() method of the Interception class.  The Initialize() method is presumably triggered with this statement:

Since the Initialize method is virtual, one solution would be to (1) make a “CustomAttributePolicy” class which is registered in (2) a “CustomInterception” derivation which overrides Initialize().

However, this strikes me as overly-intrusive and not as flexible as the next option.

Again, since PolicyInjectionBehavior is constructor-injected with an array of InjectionPolicy instances, the same goal can be achieved simply with a supplemental registration after Interception is added and before policy-based registrations are made:

Now when Unity resolves an object such as ITenantStore, the PolicyInjectionBehavior will be given the additional LoggingAttributePolicy.  That policy, reflected from Unity and modified for my own custom logging and LoggingAttribute, looks like this:

Note: The ‘ReflectionHelper” seen above is actually part of Unity.

Now this custom code can be placed into an infrastructure component, and the LoggingAttribute it “seeks” can be kept separately in an application business assembly where it can then annotate business objects without causing a dependency on Unity:

So if you’re using Unity AOP and attributes, you now have the fix to keep your architecture clean.

Facebook Security Alert! Random Account Possession

I just got done posting a Facebook message in an account that was not mine. It started with me being logged in with Chrome into my own Facebook account. After a few minutes of casual browsing, “liking,” and following links…I then noticed that my Facebook account was greeting me as somebody else! No, I did not hijack a cookie from a prior user session. The account I suddenly “possessed” was that of one of my Facebook friends living a thousand miles from me and who had never physically touched my computer before. The only feasible explanation is that Facebook session, content data, and state management got into a tangle.

To minimize skepticism of this event, I left a post in the possessed Facebook account.

Over the years I’ve encountered a number gross flaws in any number of commercial web sites. In the even fewer times where I actually took the time to contact the pertinent company, I’ve usually been told “we’re sorry your web access isn’t working.” In other words, they can’t grasp that I’m trying to tell them about a serious defect in their software. But for all that this current experience, and the related gravity, is a first for me. I figure if I write it up in a post, it will help to clarify and prevent the usual “sorry for your broken web access” response.

ASP.NET Debugging: Pick Your IIS Site?

In web-related Visual Studio projects, under the project-properties->web tab there is an option to “Use Local IIS Web server.”  In turn, that option provides a “Create Virtual Directory” button.

Having more than one site configured in my local IIS, the first question I asked when I saw that was “into which IIS web site will it create this virtual directory?”

Since it was painful to figure this out, I’ll share the results in hopes it will help another.  Simply put, Visual Studio will choose the first web site that:

  1. has a binding that matches what Visual Studio has indicated in the “Project Url” entry (e.g. “http://localhost/MyApp”)
  2. is already “started”
  3. has the lowest site ID number.

For example, if three of your five sites have a matching binding, but those three sites are currently in a “stop” state, then the final tie-breaker is the site ID number.  Most of the time, the site that wins this selection process is the IIS “Default Web Site.”

So if you want to pick a different site than what Visual Studio would pick, either (1) adjust the “stop” and “start” states of your sites or (2) in Visual Studio, for the “Project Url” entry, add a port number (e.g. http://localhost:88/MyApp) and be sure there is a corresponding IIS site that listens on that port.

Using either option above, after hitting the “Create Virtual Directory” button in Visual Studio, the site application will then appear where you intend it.  Of course assigning a host name to an IIS site, and using that in Visual Studio’s “Project Url” should also work, but that wasn’t the scenario I was concerned with…

ANTS and Orchard CMS

If you’ve tried profiling Orchard with ANTS, you’ve probably gotten this YSOD message:

Operation could destabilize the runtime

To solve this problem, download the Orchard source and open the Visual Studio solution. In the AssemblyInfo.cs of the Orchard.WarmupStarter project, add this:

It does not matter if this step is taken before or after you “cook the recipe.” But before you start the ANTS profiler, be sure to clean and/or re-build the solution.

I’ve tried this fix successfully with IIS, IIS Express, and with Orchard version 1.4.0, 1.4.1, and 1.5.1. In all cases, I was using SQL Server Express for the database and ANTS Performance Profiler 7.3 Professional.

Of course if ANTS is not your thing, you could try the Eqatec profiler or DotTrace.

A New Adventure in The Great Recession

The Gig is Up!

The Great Recession had led me into FTE, as I then felt a permanent position would provide better security. However, I eventually concluded that consulting remains as durable as ever, and it is still the venue where I’m able to make the best contributions.  So naturally I was thrilled when the opportunity came to jump back into consulting with a big splash.

My newest adventure goes like this: American Express bought a company called Serve Enterprise. Contrary to the Amex IT strategy, Serve is Microsoft stack.  So Amex had Microsoft consulting brought on board to provide guidance. In turn, Microsoft engaged me (AxisCode LLC) as a subcontractor.

Thus I’ve joined the Amex/MS platform software architecture group, where I provide guidance on ASP.NET MVC3, WCF, performance engineering, security, testability, etc. I’m often traveling between Phoenix, my home, and St. Petersburg Florida. I was certainly was daunted with so much travel, over such a long distance, but it worked out!

The engagement and the team are fantastic. I couldn’t have hoped for better.

Maximizing Return

In a corp-to-corp engagement like this, I prefer to include expenses into my hourly rate and then see how much money I can save by cutting travel costs. So, part of my adventure has been exploring my cost-savings options.  Other than purchasing air-fare 3 weeks out, there is nothing I can do to reduce that cost.  That leaves lodging and auto-rental.  The hotel used by some of the other contractors is $180/night, and even if they obtain a corporate rate at $120/night for four nights a week, it still means about $2000/month.   Worse than this, I have recently taken on a new self-imposed diet that requires I greatly reduce eating out;  I can’t prepare meals in a hotel room.

My next stop was to consider Extended Stay hotels.  I found the best deal in the St. Petersburg area (Clearwater to be precise).  At $300/week it was at a sweet spot for quality and price.  Unfortunately it is 10 miles from the downtown office where I work, which means I’m footing a $200 to $260 rental car each week.

I then decided to be more creative.  I looked into being a house-mate in a home or condo.  My first stop was roommate.com.  It is a great web site, and I didn’t mind the modest subscription fee.  However, what I found is that far too few home-owners know about roommate.com.  Rather, craigslist was a firehose of opportunity.  More than half of the offerings included furnishings (bed, dresser, etc.).  In a single evening I located three condo owners all in walking distance to both my work and groceries.  All three had pictures showing a beautiful residence.

This was my ticket.  As a house-mate, not only did I find living quarters that are much nicer than the hotels (!!!), I’ve also reduced my monthly lodging and auto expenses to less than half.

If you are reading this and are thinking of doing the same thing, my advice is to seek a place to be a house-mate after you have already started your new engagement.  This means you should start your engagement living at an Extended Stay hotel.  Assume you will need to stay there for about two to four weeks.  When you search craigslist for rooming opportunities, hold out for best!  There is no need to stay in a home that feels wrong, or is distant from your work place.  There are fresh postings on craiglist each day; I bet it will take you very little time to find something awesome.  If you do room somewhere that is not in walking distance of work, at least be sure it has walking-access to suitable public transit.

Keeping It Fresh

Life is what happens while you make other plans.  This is one reason I welcomed this long-distance consulting shake-up, contrary to my normal working arrangement, and I’m having a blast. To the reader, my suggestion is not to wait-out the Great Recession.  Make your move now, to live a new adventure now.  You won’t regret it.

New Orchard CMS Screencasts!!!

I’ve finally completed my screen-cast “jump start” demonstration of the Orchard CMS. The four part series can be viewed on youtube:

I made these videos for two reasons. First, it is somewhat a sales-pitch for the work place. You know, try to get your employer hooked! Second, I wanted to give back to the community; I saw a need for a mid-level overview for technical types new to Orchard. After watching these videos, the uninitiated should quickly be able to understand most any subsequent documentation they encounter.

Speaking of which, I want to take this time to indicate what I think are the best pieces of documentation available for Orchard. Obviously the Orchard site official documentation is a primary place to get started. However, for technical types, there are two other sources that I can’t recommend highly enough:

After watching my screencasts, be sure to immerse yourself in the above links. And speaking of my screencasts…

The Good, the Bad, and the Funny.

Funny: Sometime after I made the material for part 1, I noticed that my demo restaurant “Cowboy Ciao,” was misspelled. It is a real restaurant, which I highly recommend, in downtown Scottsdale. But the demo incorrectly captured its name as “Cowbory Ciao.” I keep picturing Jackie Chan helping me with pronunciation. I quietly fixed this typo in the later videos. Adding insult to injury, I stated in the video that it is in downtown Phoenix, rather than Scottsdale. I hope I don’t get sued for being geographically challenged.

Bad: My videos are based on Orchard 1.3.10, and I released them precisely when Orchard 1.4.0 was released. DOH! The good news is that I don’t believe 1.4.0 changed anything about what I had demonstrated in the videos.

Good: Another coincidence. I demonstrated how to use rule-tokens in the context of comments notification, and at the same time Bertrand blogged comment related tokens in greater depth. A nice one-two punch.

Good: While I was making the demo for comment notification rules, I found a bug which the Orchard team dispatched effortlessly. Orchard 1.4.0 was given the fix just before its release date, and I think 1.3.10 may have been given it as well.

Ok, enough talk. Get thee to youtube, watch my videos, and get to know Orchard!

setAttribute Bug

The book “Javascript: The Definitive Guide” says “these methods (getAttribute and setAttribute) use standard attribute names, even when those names are reserved words in JavaScript” (6th edition, p 376).  But as it turns out, this is incorrect where IE7 is concerned.

To demonstrate this, consider the code below. If you can access “compatibility mode” of IE, notice that the “one two three” result stacks horizontally in IE with compatibility mode off, but stacks vertically in IE with compatibility on (e.g. imitating IE 7).

To work around this issue, without requiring jquery, simply replace the setAttribute call with a direct assignment to the predefined “className” attribute.

You can try this solution by editing the code above (hit the plus symbol in the top right corner). Just uncomment the “className” assignment line, and comment the setAttribute line. Then toggle compatibility mode again – the horizontal format then becomes consistent!