-
Notifications
You must be signed in to change notification settings - Fork 7
Home
Aspectacular is the best AOP framework for the .NET in the age of LINQ. It is written not by a framework-oriented shop, but rather by someone who is a practicing Enterprise application developer, who is dog-fooding this framework and for whom a framework is not an end in of itself, but rather means to an end.
Aspectacular is an attempt to create a simplest possible .NET AOP aspect injector without imposing scary and esoteric nuances of AOP/IoC onto feature-function developers. An idea to make this framework came from observing how real-world Entity Framework and Web Services DAL/BL tier code is written, and how abundant boilerplate code is in it.
Main differentiators of this framework are:
- It supports interception of non-virtual instance methods, as well as static methods.
- Instead of only two usual "before call " and "after call" cut points, this framework has 7 cut-points in method's life cycle.
- Has an ability to specify aspects in multiple places, like .config file, global factory, and point of invocation.
- Provides consistent way of collecting logging information generated by aspects, Proxy, and method itself. Aspects that collect logs and store/output them are separated.
- LINQ-oriented. This framework has many features related to making it very LINQ-friendly, including ability to trip the enumeration wire.
- Wraps more than methods: IDisposable, new() classes can be instantiated before and cleaned up after the wrapped method is called by the proxy.
- Comes with out-of-the-box set of valuable aspects, including logging, retries, caching, DTC transactions, claims-based authorization, SQL connection augmentations, and others.
- With run-time weaving, intercepts 3rd party methods that were not even envisioned to be interceptable.
This project is primarily focused on wrapping Data Access Layer (DAL), Business Logic Layer (BL), and Web Service Tier (WS) calls in a way that allows aspect classes to intercept and intercept/augment/expand them. The end result is a way of calling BL without having to explicitly maintain connections, explicitly handling exceptions, explicitly logging call outcomes, etc. All these auxiliary tasks, a.k.a. cross-cutting concerns, are left to the variable set of injectable aspect classes, which can be different from one caller tier, say, UI, to another, like Testing.
AOP is great, but AOP frameworks tend to be complex, with steep learning curve. This project narrows the scope of AOP approach to mostly injecting aspects (logging, audit, performance monitoring, authorization, exception handling, etc.) into DAL/BL methods written in .NET, in a simplest way possible, w/o requiring feature-function developers to understand what AOP is.
To learn by stepping through the code, simply clone the repo and trace the TestOne() unit test method in debugger. It shows the same method called twice: first, a regular instance method call, and second, same method called using AOP proxy - that's the easiest entry point into learning about what AOP is all about, and what Aspectacular can do for you. Or read more below.
For example, here's one may want to replace a frequently-used pattern of DAL/BL invocation with Aspectacular AOP Proxy based interception: Before:
using(var dbConn = new SomeDbOrEntityConnection())
{
var resultSet = dbConn.DalOrBlMethodCall(parm1, parm2);
}
After:
public static Aspect[] Aspects
{
get
{
return new Aspect[]
{
DebugOutputAspect(),
RequestCache.Get().CreateCacheAspect(),
new ReturnValueLoggerAspect(),
new LinqToSqlAspect(),
new SqlConnectionAttributesAspect(),
};
}
}
...
// BL call from UI, web service or test tier:
var resultSet = AOP.GetDbProxy<SomeDbOrEntityConnection>(Aspects)
.Invoke(blContext => blContext.DalOrBlMethodCall(parm1, parm2));
Above-mentioned passing methods-to-be-augmented as anonymous delegates to the AOP Proxy is the mainstay of Aspectacular. In general, this whole thing is about binding DAL/BL calls to aspects, and in most cases what you'll do is as simple as either:
// Static methods:
var result = AOP.GetProxy(optionalAspects).Invoke(() => StaticDalBlMethod(parm1, parm2));
or
// Instance method
var result = someInstance.GetProxy(optionalAspects).Invoke(instance => instance.DalBlMethod(parm1, parm2));
It's really this simple. The rest is just plugging in existing aspects and creating your own. To see how easy it is to create your own aspect class, look at this example, where four useful aspect classes are done in 100 lines of code.
There are many useful auxiliary features, like additional AOP proxy subclasses wrapping Entity Framework DbContext and ObjectContext, automating away lots of boilerplate code like instantiating/disposing of DbContext instance, calling ToList() on an IQueryable result, and calling SaveChanges() at the end - just so you could keep your code clean and simple, focused on calling single DAL/BL or Web Services.