Skip to main content

Posts tagged with 'aspect'

In the previous post, we got the aspect to communicate with the service object by using args.Instance. But it only really works for one service: TerritoryService.

How can we get it to work with other services?

One approach would be to add a bunch of casts and if-statements:

I don't like that approach much. Another approach would be to create a base class that all our service classes would inherit from. I generally try to avoid this approach as much as possible, but I think it makes sense in this case. We could create an interface, like IHasValidationCallback, but let's take it one step further and create an abstract base class that already contains the implementation.

Now that the TerritorySerivce (and our other services) have a ServiceBase base class, we can update the aspect to use ServiceBase.

And there you have it: as long as all the services in the namespace inherit from ServiceBase, this will work.

So I think we're making progress, but let's review the issues from last time:

  • This only works for ITerritoryService--what about the other services? We just addressed this one.
  • Swallowing exceptions: we should at least be logging the exception, not just ignoring it.
  • If the method has a return type, then it's returning null. If it's meant to return a reference type, that's probably fine, but what if it's returning a value type?
  • What if it's returning a collection, and the UI assumes that it will get an empty collection instead of a null reference?
  • Do we really want to return the exception message to the user?
  • NEW ISSUE: What if I forget to use ServiceBase as a base class on a new service?

Yep, we fixed one issue, but we really just shifted the problem to a base class that could easily be overlooked. Next time, let's see if we can get PostSharp to help us with that.

In the last post, I laid out the bare essentials of an error handling aspect for my service layer.

Before I proceed further with the aspect, let's examine the layer right above the service layer: the UI layer. I'm using ASP.NET MVC.

With ASP.NET MVC, there is a concept of ModelState, which holds information about validations performed during model binding, and is also used by the controller to convey error information to the view (through the Html.ValidationSummary helper, for instance). I'm already using ModelState to convey simple validation errors; I'd like to use it to convey any errors that the service layer might encounter. There are many ways to approach this; I've chosen the "callback" approach--passing a lambda to the service layer in order to communicate error information from the service layer up to the UI layer. Here's the basics:

Dependency injection gives me an object that implements the ITerritoryService interface, but I have to take one more step and pass that service the lambda x => ModelState.AddModelError("", x) in the controller instructor. This is because ModelState doesn't actually get instantiated until the controller does (so I can't pass it to the service object any sooner).

Now, when there's an exception in Territory service, I can simply use this "callback" to add an error to the ModelState. (Side note: a benefit to this approach is that it does not couple TerritoryService to my UI: if I wanted to use this service with another UI--say, WebAPI or WebForms--then I would simply have to pass in a different lambda).

Let's get the aspect to use that callback.

By using args.Instance, we can get a reference to the object in which the method resides. If that object can be cast to ITerritoryService, then we can simply call AddModelError. This works great: now anytime there's an exception in TerritoryService, it will be added as an error to ModelState and displayed to the user.

But clearly there are still issues here:

  • This only works for ITerritoryService--what about the other services?
  • Swallowing exceptions: we should at least be logging the exception, not just ignoring it.
  • If the method has a return type, then it's returning null. If it's meant to return a reference type, that's probably fine, but what if it's returning a value type?
  • What if it's returning a collection, and the UI assumes that it will get an empty collection instead of a null reference?
  • Do we really want to show the exception message to the user?

Next time, we'll start addressing the first issue, and figure out a way to make this aspect more generic.

I've written a lot of AOP demos, given a lot of presentations on it (AOP For You and Me and The Class That Knew Too Much), and I even wrote a book about AOP in .NET. These aspects are all great places to start, but I thought I would take it a little deeper in a blog post series, detailing a real aspect I'm using in a real project, how I built it, and the reasoning behind the decisions I make. Because this is a much more practical example, this aspect is not generally applicable. You can't just drop it in to your project without tailoring it a bit. (If you are interested in those types of aspects, PostSharp has custom design patterns, ready for you to use today).

I'm only going to show you the basics of the aspect right now, and I'll build it up and add to it as this blog post series goes along. Note that this is an active project, and therefore it's still a work in progress. Part of the reason I'm doing this series is to help me get some real feedback!

My goal with this aspect is add error handling to my service layer. This service layer sits between my UI layer (an ASP.NET MVC application) and my data layer (which uses Dapper on a SQL Server database). When this aspect is done, it should:

  • Catch exceptions
  • Log (most) exceptions
  • Ensure that a useful/helpful/friendly error message is given to the UI, instead of bubbling up the exception
  • Make sure the service method returns something useful, if it's meant to return something

As an aspect, then, I can apply this to every public service method so that I don't have to worry about writing it over and over, and I don't have to worry about forgetting to add it to new service methods.

Let's start easy with a basic shell of an aspect:

I'm using MethodInterceptionAspect. I guess I could use OnMethodBoundaryAspect instead (or even OnExceptionAspect), since most of the code I'm going to write is going to end up being in that "catch" block. But let's just stick with this for now, and consider changing later (because of how PostSharp's API is structured, I know that this won't be very difficult).

Notice that there are two attributes on this aspect.

As it stands right now, this is not a good aspect, since it will just be swallowing all the exceptions. But it's as good as place to start as any, especially if you aren't familiar with AOP/PostSharp.

I'll also create another file in my project called Aspects.cs, which will contain assemly attributes so that I can apply this aspect to every method in the namespace where I put all my services.

I put an AspectPriority of "10" on it because I actually have another aspect in my project that I use to manage SQL transactions that has a priority of "20". I want the exception handling aspect to be the highest priority (lowest number).

Make sure you understand what's going on here before continuing. If not, you may want to review those presentations I linked to, check out the PostSharp documentation, or maybe check out my PostSharp Live webinar series.

This week, there's a Manning Publishing promotion brought to you by my friends at PostSharp! This week of deals will bring you 50% off of a whole bunch of great .NET and/or AOP related books, including mine. You'll also get free excerpts from each book, so you can try before you buy.

Today, you can get my book, AOP in .NET, for 50% off, using code dotd0819au.

These are the Promotional Codes that will be active all week:
 
Day One: Save 50% on C# in Depth, Third Edition and Real-World Functional Programming. Enter pswkd1 in the Promotional Code box when you check out. Expires midnight ET August 20. Only at manning.com.
 
Day Two: Save 50% on AOP in .NET and AspectJ in Action, Second Edition. Enter pswkd2 in the Promotional Code box when you check out. Expires midnight ET August 21. Only at manning.com.
 
Day Three: Save 50% on ASP.NET MVC 4 in Action and ASP.NET 4.0 in Practice. Enter pswkd3 in the Promotional Code box when you check out. Expires midnight ET Aug 22. Only at manning.com.
 
Day Four: Save 50% on Metaprogramming in .NET and DSLs in Boo. Enter pswkd4 in the Promotional Code box when you check out. Expires midnight ET Aug 23. Only at manning.com.
 
Day Five: Save 50% on Brownfield Application Development in .NET and Continuous Integration in .NET. Enter pswkd5 in the Promotional Code box when you check out. Expires midnight ET Aug 24. Only at manning.com.
 
Day Six: Save 50% on Windows Store App Development and Windows 8 Apps with HTML5 and JavaScript. Enter pswkd6 in the Promotional Code box when you check out. Expires midnight ET Aug 25. Only at manning.com.

So, if you are a .NET developer, a web developer, or just trying to learn some more skills, this is the week for you!

Some AOP books

March 21, 2012 mgroves 0 Comments
Tags: AspectJ csharp books Java

As far as AOP goes, there's not a great selection of books out there. I've only found 3 that might be worth reading (I haven't read any of them yet):

  • AspectJ Cookbook by Russ Miles, published by O'Reilly in December 2004. From the reviews, this seems to be a "how" book, and very specific to AspectJ.
  • AspectJ in Action by Ramnivas Laddad, published by Manning in July 2003, second edition in October 2009. This may be the most popular book on AOP, even though it's focused on AspectJ.
  • Using Aspect-Oriented Programming for Trustworthy Software Development by Vladomir O. Safonov, published by Wiley in May 2008. I only discovered this one recently. The author of this book is also the creator of Aspect.NET, but apparently it mentions other AOP tools as well. The price tag is a little steep, and since it was written by a professor, I'm guessing it will be very academic and dry.

That's pretty much it. Two books for Java developers from the mid 2000s, and one book for .NET developers from 2008. Am I leaving anything out? I know other books touch on AOP (like Clean Code by Robert C. Martin, which I highly recommend), but not many that really dive deeply into it.

Matthew D. Groves

About the Author

Matthew D. Groves lives in Central Ohio. He works remotely, loves to code, and is a Microsoft MVP.

Latest Comments

Twitter