SheepAspect: Mixin

SheepAspect Preview-3 was released today, and one of the most important new features is Mixins. In Preview-2, there were only one advice implementation: [Around]. In preview-3 we introduce two more advices: [DeclareMixin] and [DeclareAttributes].

[DeclareMixin] advice allows you to add new interface implementations on existing classes. As an example, here is a plain simple Customer class:

public class Customer
{
	public string FirstName {get; set;}
	public string LastName {get; set;}
}

And a completely unrelated IEmailable interface:

public IEmailable
{
	public string EmailAddress {get; set;}
	public void SendEmail(string subject, string body);
}

Now let’s stitch these two together using SheepAspect mixin

[SingletonAspect]
public class SmtpAspect
{
	[SelectTypes(typeof(Customer))]
	public void Customer(){}

	[DeclareMixin("Customer")]
	public IEmailable CreateCustomerEmailable(Customer customer)
	{
		return new CustomerSmtpEmailable(customer);
	}

	private class CustomerSmtpEmailable: IEmailable
	{
		private readonly Customer _customer;

		public CustomerSmtpEmailable(Customer customer)
		{
			_customer = customer;
		}

		public string EmailAddress { get; set; }

		public void SendEmail(string subject, string message)
		{
			/* Just pretend this code is going to an SMTP server, not to a console */
			Console.WriteLine("To: {0} {1} ({2})", _customer.FirstName, _customer.LastName, EmailAddress);
			Console.WriteLine("Subject: {0}", subject);
			Console.WriteLine("\nMessage:");
			Console.WriteLine("Hola {0},", _customer.FirstName);
			Console.WriteLine(message);
			Console.WriteLine("\nSincerely yours");
			Console.WriteLine("Sheep");
		}
	}
}

With this aspect in place, your Customer class now magically implements IEmailable interface. The invocation will be directed to the implementation we have provided in our aspect (CustomerSmtpEmailable), which contains the infrastructure code of sending an email through an SMTP server or background tasks. Now you can actually cast your Customer arbitrarily to an IEmailable:

var customer = new Customer {FirstName = "Henders", LastName = "Sheep"};

var emailable = (IEmailable) customer; // Casting a Customer into IEmailable!

emailable.EmailAddress = "henders.sheep@foo.com";
emailable.SendEmail("Buy now!",
    "We have a great collection of sheep for you to buy.\nHurry, while stock lasts!");

That actually works, and you did not get InvalidCastException. Instead you’ll get this little output on your console window:

image

All source-code in this example can be found in SheepAspect.Example project on SheepAspect code repository.

Binding Mixins to Fields

Instead of declaring Mixin implementation factory method, you can also bind your Mixin implementations on aspect fields. For instance:

[SingletonAspect]
public class SmtpAspect
{
	[DeclareMixin("CustomerTypePointcut")]
	public IEmailable _customerEmailable;
}

Now your Customer will implement IEmailable interface that directs its execution to the IEmailable instance held by this _customerEmailable field on your SmtpAspect. Swapping the implementation of your Customer’s IEmailable is as simple as setting the value of this field.

Dependency Injection: Reborn

Some time in our career, we have learnt about separation of concerns, about how you should split domain-code from infrastructural concerns. Usually this is achieved by means of dependency-injection, the goal of which is to promote loose-coupling, maintainability, and testability. Dependency-injection has become one of the most fundamental principle in OO application development. But this is a principle that might no longer be relevant in AOP world.

The premise of dependency-injection does not necessarily hold true in AOP development process. There is no longer much need of rearchitecting your classes to fit into dependency-injection scheme just to achieve separation of concerns. You can in fact just implement your infrastructural concerns directly as part of your Customer domain class. For typical CRUD applications, you can do away without repository classes: you just simply inject ActiveRecord capability straight onto your entities through mixin.

Feeling dirty? Not quite. Separation is still maintained because these implementations are actualised as separate mixins that are injected externally by aspects where you consolidate all your infrastructural plumbing.

In our Customer/IEmailable example, neither your Customer class, IEmailable interface, nor their consumers are aware of any SMTP implementation. They are pure POCO. Then somewhere completely external to the core of your application code, you just introduce SmtpAspect mixins aspect where you actually implement your SMTP plumbing, and will statically enhance your customer class with SMTP capability. But from code perspective, your Customer class remains a simple POCO model.

For unit-testing, you can mock SmtpAspect class, and reimplement the IEmailable behavior with mocked behaviors.

Yes you do violate dependency-injection principle, you sinfully commit God-Object anti-pattern, but hey, those wisdoms was invented before the birth of AOP into static languages.

SheepAspect Preview 3

This is not a massive release or anything. The idea is to push new changes rapidly to the public to attract early feedbacks, especially because this Preview3 release comes with a good set of new features and improvements that I genuinely feel very excited about. Many of these changes are based on feedbacks I have received from early adopters. So thanks to everyone who has shared their inputs.

What’s New

There is no significant changes on the underlying SheepAspect framework itself. This release is more of implementing new functionalities and natural progression of the feature-set of the library. Some of these new features are:

  1. The most significant new feature in Preview3 release is the Mixins support. With the new [DeclareMixin] advice, you can now statically add interface implementations to existing classes. I will write have written the details of this in a separate post.
  2. We also now have [DeclareAttributes] advice attribute. With this advice, you can statically add attributes to existing types, methods, properties, fields, and constructors. This will also be covered in the upcoming posts.
  3. IAspectAware interface, so you can now intercept when your aspects get instantiated by AspectRuntime so you can execute some initialisation routine. Again, this will be covered in the upcoming posts.
  4. A more complete set of pointcut implementations. Preview-2 advices could only target methods, properties, and instructions (method-calls, field gets/sets). In preview-3, they can also target types, constructors, fields, and property getters/setters. Events are only partially supported at the moment.
  5. Intellisense documentation. I understand that SheepAspect has a very steep learning curve. It can be overwhelming for users to get started or to figure out what each attribute does. In this Preview 3 release, most of SheepAspect’s public API is well documented.
    image10image9
  6. In Preview 2, SheepAspect required pdb files of all target binaries (so that SheepAspect can preserve debuggability of your weaved binaries). This has caused a problem for users who do not have pdb files of their target binaries. In Preview 3, pdb files are optional.

Get It Now

As usual, SheepAspect Preview3 is installable from NuGet: https://nuget.org/packages/SheepAspect. SheepAspect-Query-Analyzer for Preview-3 version is still due to come soon, and will be downloadable separately on the SheepAspect homepage.

UPDATE: SheepAspect-Query-Analyzer is now always included when you install via NuGet, under the Tools directory within the SheepAspect package folder.

SheepAspect Preview 2!

I’m very excited to announce the second preview release of SheepAspect. It’s available now, and you can install it to your project from NuGet gallery.

There are few new features introduced on this release, such as changes around its API, introducing more simplicity, bug fixes, and improved implementations. But there are few things that I’d like to highlight what’s new in this release.

NuGet Package

Previously, installing SheepAspect has always been a bit of a mess. You had to reference few libraries into your project, copy some compiler.exe into a folder, modify your csproj manually to include the compiler into your build-task, and pray all the stars are lined up in a perfect angle.

Now in Preview-2, NuGet will do all the mundane heavy-lifting for you. The only step you need to do now is to NuGet SheepAspect straight to your main project, and that’s it. Everything will be configured for you, and you’ll be all set to go before you finish reading this sentence.

When you NuGet SheepAspect into your project, there are 4 things that happen:

  1. It downloads all binaries and compiler into your project, and attach the necessary runtime libraries into your project references.
  2. It modifies your .csproj/.vbproj file to hook SheepAspect compiler into your post-build task.
  3. Generates a default configuration file (SheepAspect.config) and add to your project. This file has been pre-configured to just work immediately, which you can then use as a starting point to configure your SheepAspect settings. (More about this below).
  4. You’ll also be given one sample aspect class (/Aspects/SampleAspect.cs), and all it does is trace-logging around all public methods within your current project. (Entry, exit, exceptions).

The included sample-aspect is readily active and all fully functioning out-of-the-box, so that as soon as you nuget SheepAspect into your project and hit run immediately, you’ll watch all your public methods are now writing log traces to your debug window. From here, you can use this sample ‘SampleAspect.cs’ as a template to get started to write your very own first aspects.

SheepAspect.config

Another new feature introduced in Preview-2 is an easier configurability. So instead of tinkering with your .csproj/.vbproj msbuild tasks to configure SheepAspect compilation settings, you can now do so in SheepAspect.config. When you install SheepAspect, you’ll get a default config:

<?xml version="1.0" encoding="utf-8" ?>
<sheepaspect-config xmlns="urn:sheepaspect-config-1.0">
  <aspects>
    <assemblies>
      <include>YourProject.exe</include>
    </assemblies>
  </aspects>
  <weave>
    <assemblies>
      <include>YourProject.exe</include>
    </assemblies>
  </weave>
</sheepaspect-config>

It’s pretty straightforward. The xsd file is included so you can use Visual Studio intellisense to view all the different settings, although it’s all pretty basic at this point.

Build Report

SheepAspect compiler task spawns a separate (console) process to get around Visual Studio annoying tendency to lock dll files that you access during the task. That’s why in Preview-1 you could briefly see a console window popping up during compilation process. When an error occurs during the compilation, you’ll need to read the report printed on the console window.

The new SheepAspect is still using the same technique, but it’s more refined and well hidden. You won’t see any window popping up, and your compilation results will be reported nicely on your Visual Studio.

SheepAspect Query Analyzer

I have announced SAQA before, but this is the first time it has ever been released. SAQA’s releases will roughly follows the release cycle of SheepAspect, but it’s distributed as a separate download. You can download SAQA for SheepAspect Prevew-2 here on the project website.

Factory Per Aspect

Aspect factory determines how your aspect classes are instantiated during runtime. In the previous version, aspect factory was defined globally.

AspectFactory.Current = new StructureMapAspectFactory(structureMapContainer);

But there are times when you need to use a specific factory for your particular aspect. For example to instantiate your aspect from attribute declaration, or to instantiate from web-request (model-binding) or client cookie. New in Preview-2, now you can define your factory on a per-aspect basis.

[Aspect]
[AspectFactory(typeof(AttributiveAspectFactory))]
public class MyAspect
{
}

If no particular factory specified for your aspect, SheepAspect will resort to a global default factory.

AspectRuntime.Provider.DefaultFactory = new StructureMapAspectFactory(structureMapContainer);

That’s right, you’ve just seen AspectRuntime there. It’s a new addition in SheepAspect Preview-2 that gives you access to the runtime environment of your aspects. You can, for example, switch off all your aspects (or a specific aspect) for unit-testing purpose, or even to replace your aspect with a mock. You can inquire the lifecycle of your specific aspect, or even change them (e.g. from Singleton to PerThis). You can ask for the instance of a specific aspect for a particular jointpoint, and so on. It gives you a flexible and dynamic control upon your aspect-orientated runtime behaviors that can’t be scripted during compile-time alone.

SheepAspect

This is also the first release since the project changed its name from SheepAop. So if you’re using Preview-1, the upgrade path to Preview-2 will be a breaking and rocky one. But I’m very excited about this release, I’d strongly urge to to upgrade if you’re already on Preview-1, or to start trying out and play around with SheepAspect if you haven’t. So go on, it’s only a NuGet away 😉

These preview releases have always been about giving people an early access to gather as much feedback as I can. So any comments/issues/suggestions, as always, would be greatly appreciated 🙂

[More about SheepAspect]

SheepAspect Query Analyzer

SheepAspect-Query-Analyzer (aka SAQA, not to be confused with Sucka’) is a simple tool I built to let you quickly punch in your SAQL pointcuts, and execute them immediately against your assembly files to get instant results.

The GUI is quite plain and basic, but it does the job.

This tool will hopefully come in handy for developers to get into SAQL pointcuts and syntax. You just simply punch in your pointcut attributes on the text editor as you normally would on C#. E.g.

[SelectMethods(“Name:’Get*’ & Public”)]

You will then get instant feedbacks from this pointcut by executing it against your assemblies, which will bring back all the jointpoints it picks up (i.e.: all public methods with names starting with ‘Get’). Since it takes standard syntax of C# attributes, once you’re happy with the result, you can just copy this line straight onto your C# class.

You can type in as many pointcuts as you wish on the text-editor. You can also define aliases using ‘=’. E.g.:

[SelectMethods(“Name:’Get*’ & Public & InType:@NhConfigTypes”)]
NhConfigTypes = [SelectTypes(“Namespace: ‘NHibernate.Cfg*’”)]

Those pointcuts are equivalent to the following code on the actual C# class:

[Aspect]
public class MyAspect
{
   [SelectMethods("Name:'Get*' & Public & InType:@NhConfigTypes")]
   public void Pointcut1() {}

   [SelectTypes("Namespace:'NHibernate.Cfg*'")]
   public void NhConfigTypes(){}
}

SAQA is available for download from the latest SheepAspect trunk. SAQA will also be included as part of the next SheepAspect release.

What’s next?

  • Keyboard shortcuts
  • Ability to save the progress of your SAQA workspace
  • Ability to view and open the source-code of your joint-points in Visual Studio
  • SAQA will be able to read from SheepAspect configuration file (that will be introduced, hopefully, in the next SheepAspect major release)
  • I have NO plan to deliver any intellisense functionality, but feel free to send me a patch

SheepAop Is Now SheepAspect.org

I admit I didn’t spare much thought into the name when I started the project. I just simply followed the infamous Luk’s rule of project naming: “append the word ‘Sheep’ with something boringly obvious about the project”. Hence SheepAOP. It was just a random codename I picked for a project that was intended at that time as my own personal proof-of-concept on one rainy weekend. And I went slightly overboard with it without bothering myself to change to a friendlier name, and the name “SheepAop” managed to see the light of day.

It’s not a friendly name, and quite a mouthful to say, thanks to the double vowels in the acronym “AOP”. I’ve lately started develeoping an involuntary cringing habit on the sound of “SheepAOP” produced by my mouth every time I talk to people. And I hate cringing. Something has to be done about it. Changing my habit is a bit complicated, so instead I renamed the project.

So it’s official, the project is now called SheepAspect. It has found a lovely home at SheepAspect.org, and the source-code has been refactored to embrace the new name (which is obviously a breaking change). The old url (sheepaop.codeplex.com) still works fine and simply redirects you to the new address. So once again, say hi to SheepAspect, please help it feel comfortable with its new name.

SheepAop Part 5: Aspects Inheritance And Polymorphism

This Series

  1. Getting Started with SheepAOP
  2. Pointcuts and SAQL Basics
  3. Aspects Lifecycles & Instantiations
  4. Integrating with IoC containers
  5. Aspects Inheritance & Polymorphism
  6. Attributive Aspects (ala PostSharp)
  7. Unit-testing your aspects
  8. Extending SheepAop

Reusing Advices

Think back to the concurrency example from our previous post. We used the ReadWriteLockAspect to define the reading and writing operations within our ShoppingCart, and apply a read/write locking pattern onto it. Surely we can apply this same pattern to other classes where a safe concurrent access is required. We can refactor this well-tested concurrency pattern into an abstract aspect that we can reuse instead of reimplementing it when we need it again.

This gives us a perfect situation to demonstrate SheepAop’s modularity and reuse, as we refactor our ReadWriteLockAspect example into the following.

[AspectPerThis("ReadingsPointcut", "WritingsPointcut")]
public abstract class ReadWriteLockAspect
{
   protected abstract void ReadingsPointcut(); // Abstract pointcut
   protected abstract void WritingsPointcut(); // Abstract pointcut

   protected abstract int GetTimeout(); // Abstract method

   private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();

   [Around("ReadingsPointcut")]
   public object LockRead(JoinPoint jp)
   {
      try
      {
         _lock.EnterReadLock(GetTimeout());
         return jp.Execute();
      }
      finally()
      {
         _lock.ExitReadLock();
      }
   }

   [Around("WritingsPointcut")]
   public void LockWrite(JoinPoint jp)
   {
      try
      {
         _lock.EnterWriteLock(GetTimeout());
         jp.Execute();
      }
      finally()
      {
         _lock.ExitWriteLock();
      }
   }
}

Now to apply a write/lock behavior to our ShoppingCart class, we simply extend the aspect. We just need to provide the implementation of the pointcuts. The behavior of the advice will be inheritted from the base aspect.

public class ShoppingCartLockAspect: ReadWriteLockAspect
{
   [SelectMethod("'* ShoppingCart::Get*(*)'")]
   [SelectPropertyGet("'* ShoppingCart::*'")]
   protected override void ReadingsPointcut(){}

   [SelectMethod("InType:'ShoppingCart' && Name:'AddProduct'|'RemoveProduct'")]
   protected override void WritingsPointcut(){}

   protected override int GetTimeout()
   {
      return 2000; // Timeout is 2 seconds
   }
}

Now we have used the base ReadWriteLockAspect to transform the ShoppingCart class to be thread-safe. We can reuse this same base aspect to any other target class that you intend to make thread-safe.

Tips on Pointcut Compositions: make sure you take advantage of the composability of SheepAop pointcuts when designing a reusable aspect. You can devide your pointcut into fragments to extract any reusable pattern out, and only expose a small fraction of it as abstract. As an example, our ReadWriteLockAspect can be modified to automatically apply the locks on all read/write methods and properties on the particular type that you target.

[AspectPerThis("ReadingsPointcut", "WritingsPointcut")]
public abstract class ReadWriteLockAspect
{
   [SelectMethod("'InType:@TargetClass && Name:'Get*'|'Is*' && !ReturnsVoid")]
   [SelectPropertyGet("InType:@TargetClass")]
   protected void ReadingsPointcut(){}

   [SelectMethod("InType:@TargetClass && Name:'Add*'|'Remove*'|'Set*'")]
   [SelectPropertySet("InType:@TargetClass")]
   protected void WritingsPointcut(){}

   //This is a small fragment of the pointcut that we expose as abstract
   protected abstract @TargetClass();

   /* and all the rest of it unchanged.. */
}

Now our base aspect provides a reusable template for our pointcuts, where a small fragment @TargetClass is left out as abstract to be composed to form the complete pointcut. The concrete aspect only needs to provide the implementation of this small fragment, rather than the whole pointcut expressions.

public class ShoppingCartLockAspect: ReadWriteLockAspect
{
   [SelectTypes("'ShoppingCart'")]
   protected override void TargetClass(){}

   protected override int GetTimeout()
   {
      return 2000; // Timeout is 2 seconds
   }
}

Other example

The ActorAspect example can also be refactored into an abstract class to reuse its advice behavior, but I will leave that as an exercise for the reader.

Reusing Pointcuts

In the previous example, we have used aspect inheritance to reuse a common advice behavior (read/write locking behavior) repeatedly for multiple pointcuts. Aspect inheritance can also be used to reuse common pointcut expressions repeatedly in multiple advice implementations. A common example of this is aspects for defining extensibility points in a plugin architecture.

For instance, consider you want to define an extensibility point that is triggered at the point of every bank-account transaction. So we define the following abstract aspect.

[Aspect]
public abstract class AccountTransactionPlugin
{
   [SelectMethod(@"InType:AssignableTo:'AccountBase'
            && Name: 'Withdraw'|'Deposit'
            && ArgTypes:'Money'")]
   protected void TransactionPointcut(){}

   [Around("TransactionPointcut")]
   public void AroundTransaction(MethodJointPoint jp)
   {
      OnTransacting((Account)jp.This, (Money)jp.Args[0], ()=> jp.Execute());
   }

   protected abstract OnTransacting(Account account, Money amount, Action proceed);
}

Now that we have this extensibility point defined, a third party can provide their plugins by implementing this base-class. For example, the following plugin will add a business policy to limit transaction amounts within our banking system.


public class TransactionLimitPlugin: AccountTransactionPlugin
{
   private const int CompanyLimit = 100000;
   private const int PersonalLimit = 2000;

   protected override OnTransacting(Account account, Money amount, Account proceed)
   {
      var limit = account.Customer.IsCompany? CompanyLimit: PersonalLimit;
      if(amount > limit)
         throw new TransactionOverlimitException(amount, limit);
      proceed();
   }
}

More plugins for this specific extensibility point can be added to the system by writing more implementations of AccountTransactionPlugin (e.g. a plugin to apply transaction-fees depending on the types of the account). Typically we would have a set these abstract aspects with different pointcut-expressions, each represents different extensibility point within the system (e.g. when an order is created, when a case is raised, when a conversation occurs, etc), onto which a specific plugin can be hooked and unhooked. You can jazz up this technique by adding MEF to the mix.

Note that the domain code of our application might not be designed with plugin architecture in mind. It probably does not even aware of any extensibility system that is in place. This brings us to our next point…

Speaking of Extensibility..

Extensibility has always been a chicken-and-egg problem. Many business applications require the extensibility to accomodate rapidly changing business rules, policies, and workflows, sometimes allowing extensibility by third-party developers. To achieve this, architects are often faced with underdesign/overdesign issue. If you underdesign, you may have to make massive changes later in the development cycle. If you overdesign with excessive amount of extensibility point on every method of your application, the implementation may be burdened with code of questionable usefulness.

With AOP, you can delay making design decisions for future requirements because you can implement those extensibility points unobtrusively using aspects. You can focus on the current requirement of the system.
In this respect, AOP works in harmony with YAGNI (You aren’t gonna need it). Implementing a feature just because you may need it in the future often results in wasted effort because you won’t actually need it. With AOP, you can stick faithfully to your current requirement, and if you do need a particular kind of functionality later, you can implement it without having to make system-wide modifications

Attribute-based Aspects (ala Postsharp)

(Since this question gets asked quite a lot, I will post this section again in a separate post as a handy reference)

SheepAop is not specifically built to support attribute-based declarative approach used in Postsharp. But using the rich pointcut expressions and aspect inheritance in SheepAop, it’s quite trivial to implement our own implementation. We just simply need to write this simple abstract aspect to deliver the same attribute-based functionality.

[Aspect]
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property)]
public abstract class AroundMemberAttribute: Attribute
{
   [SelectMethods("HasCustomAttributeType:ThisAspect")]
   [SelectPropertyGets("HasCustomAttributeType:ThisAspect")]
   [SelectPropertySets("HasCustomAttributeType:ThisAspect")]
   protected void DecoratedPointcut(){}

   [Around("DecoratedPointcut")]
   public abstract object Around(JointPoint jp);
}

This aspect simply defines a pointcut that matches all methods and properties that are decorated using the concrete type of this aspect. So now we can use this base attribute to create our TransactionalAttribute as an example.

[Aspect]
public class TransactionalAttribute: AroundMemberAttribute
{
   public override object Around(JointPoint jp)
   {
      using(var tx = new TransactionScope())
      {
         var result = jp.Execute();
         tx.Complete();
         return result;
      }
   }
}

That is all it. Now you can use this attribute to decorate methods and properties that you want to make transactional. For instance:

[Aspect]
public class OrderService: IOrderService
{
   [Transactional]
   public void ProvisionOrder(Order order)
   {
      // .... whatever ...
   }
}

For your convenience, the base-aspect AroundMemberAttribute is included straight out-of-the-box within SheepAop, so you don’t have to write it every time. Another variation of the base attribute is called AroundCallAttribute. They both have equivalent functionality, but whereas AroundMemberAttributes targets the bodies of methods and properties decorated with the attribute, AroundCallAttribute targets the calling of methods, getting/setting properties, and reading/writing fields decorated with the attribute.

Summary

Inheritance is a key component in making reusable aspects in SheepAop. Since SheepAop aspects are just normal POCO classes, you can make use of the same Object-Oriented techniques such as inheritance and polymorphism that we’re all familiar with. The same techniques are also used to implement the declarative attribute-based aspects that gives a lot of convenience for many simple cases.

SheepAOP Part 4: Integrating with IoC containers

This Series

  1. Getting Started with SheepAOP
  2. Pointcuts and SAQL Basics
  3. Aspects Lifecycles & Instantiations
  4. Integrating with IoC containers
  5. Aspects Inheritance & Polymorphism
  6. Attributive Aspects (ala PostSharp)
  7. Unit-testing your aspects
  8. Extending SheepAop

Aspect Factory

In the previous post, we have discussed at great length about various SheepAop lifecycles and how they affect the specific points at which SheepAop should instantiate new aspect objects. Whenever your lifecycle strategy determines that a new aspect needs to be created, by default SheepAop will look for a default parameterless constructor in your aspect class.

SheepAop lets you to can change this behavior and use your own IoC container to manage the instantiations of your aspects and wire up their dependencies. This is done by implementing your own custom AspectFactory. For example, the following code will hook SheepAop with StructureMap.

public class StructureMapAspectFactory: AspectFactory
{
   private readonly Container _container;
   public StructureMapAspectFactory(Container container)
   {
      _container = container;
   }

   public override object CreateInstance(Type type)
   {
      return _container.GetInstance(type);
}
}

And you add the following code to the entry point of your program (i.e. Global.asax in a web application)

AspectFactory.Current = new StructureMapAspectFactory(container);

All pretty straightforward. Now if you take the example aspect class from few posts back…

[Aspect]
public class PurchasingNotificationAspect
{
   private readonly INotificationService _notifier;
   public PurchasingNotificationAspect(INotificationService notifier)
   {
      _notifier = notifier;
   }

   [SelectPropertySets("Name:'StockQty' & InType:Name:'Product'")]
   public static void SettingProduct(){}

   [Around("SettingProduct")]
   public void CheckStockForNotification(PropertySetJoinPoint jp)
   {
      jp.Proceed();
      if ((int)jp.Value < 5)
      {
         _notifier.Send(Notice.Restock, (Product)jp.This);
      }
   }
}

… StructureMap will now handle the instantiations of this aspect class, including the wiring of the INotificationService dependency via the constructor.

I highly recommend to always register all your aspect classes using transient configuration on your IoC container, and to leave it to SheepAop to handle the lifecycle management of the instances.