The last couple of weeks I’ve been experimenting with the Enterprise Library as a framework to host services and aspects using an Inversion of Control principle. The application block is not finished yet, but pretty much does the job of hosting ‘services’ and weaving aspects into their implementations.
For a brief description of my view on IoC, have a look here, here and here.
This application block provides the following key functionality:
- It minimizes the coupling between software components (or services) by dependency injection.
- It solves cross-cutting concerns using Aspects.
- It Increases of composability in software design.
All of this goodness is composed using the EntLib’s configuration console and consumed by an EntLib provider. The Enterprise Library also makes it possible to edit the configuration and changing program behavior runtime.
The ServiceContainer application block comes with a sample application, FruitJuicer which demonstrates the use of the 3 main concepts used: Container, Service and Aspect.
Breaking it down, briefly… (numbers refer to the view in the configuration console below)
The Container(1) is used to collect Services and Aspects. Services can be injected into other Services or Aspects within the same container. Aspects can crosscut methods from services in the same container.
The Service(2) is an abstraction of 'any functionality', services are defined as a interface and interface-implementation. The interface is what the program (or other services) refers to; this is done to avoid a dependency to the service implementation.
Service configuration(3 & 4) are dependencies declared by a service's implemenatation. Every service implementation is allowed to declare dependencies within its contructor. A dependency can be either a service reference (4) or simple type (3). In the case of a service reference the dependant service interface is part of the constructor.
Aspects can declare dependencies in a similar manner.
The constructor from the FruitJuicerCachingAdvice(4) is shown below.
public FruitJuiceCachingAdvice(IServiceLocator svcLocator, bool enabled, int cacheDurationInSeconds)
The Aspect(5) contains logic that should be executed either before, after or instead of the invocation of a service implementation. For every method that should be cross-cutted the respective joinpoint property(6) should be set to ‘true’.
An aspect is defined as a class that implements the OlafConijn.ServiceContainer.IAdvice interface.
For every method that is cross-cut a method invocation will be passed to the ‘Invoke’ method on the IAdvice interface, the Aspect is now in charge of the actual invocation of the method and can proceed by calling ‘invocation.proceed()’.
Implementation of the GenericMethodTracerAdvice is shown below.
public class GenericMethodTracerAdvice: IAdvice
{
public object Invoke(IMethodInvocation invocation)
{
string traceMessage = string.Format("type: {0} method: {1}; parameters: {2}", invocation.MethodCall.MethodBase.DeclaringType.Name, invocation.MethodCall.MethodName, invocation.MethodCall.MethodSignature);
//BEFORE the invocation
Debug.WriteLine(string.Format("BEFORE[{0}]", traceMessage));
//invocation is passed to either the next aspect or
//the opriginal method invocation
object result = invocation.ProceedInvocation();
//AFTER the invocation
Debug.WriteLine(string.Format("AFTER[{0}]", traceMessage));
return result;
}
}
}

Download it here
Other notes to whoever would like to get their hands dirty on Services and Aspects:
1.) The solution is written (and build) using VS.NET 2005 Beta 2.
2.) The enterprise library version the solution is compiled against is the ‘guerilla version found here’. All dependant binaries are included in the ‘dependencies’ folder in the zip file.
3.) Unfortunately it is still not possible to add 2 services with the same interface to the same container. Later on this should be possible.
4.) Aspect weaving is done using RealProxy (.net framework class), in case someone wondered.
Sometimes soon I’ll try to add the following:
1.) webservice clients within the container
2.) Mixin support
3.) A demo, that interacts with other enterprise library application blocks (Logging, Exception management, Data Access, etc. etc)
4.) unit tests to document and describe framework interfaces.
5.) event service to do asynchronous processing (as described in Gregor Hohpe's talk on eventdriven architecture at TechEd, recently)
And many thanks to my dear colleagues Emile Bosch and Marc Jacobi for their suggestions and advice, along the way!