Click here to Skip to main content
Click here to Skip to main content

Creating WCF Service Extensibility through MEF (Managed Extensibility Framework)

, 8 Sep 2010
Rate this:
Please Sign up or sign in to vote.
Recently I was working on an application integration design wherein I wanted to expose service operations as extensibility points. By opening up the service operations for extensibility I wanted to create a simple message bus which can be tapped in to for application integration needs without making

Recently I was working on an application integration design wherein I wanted to expose service operations as extensibility points. By opening up the service operations for extensibility I wanted to create a simple message bus which can be tapped in to for application integration needs without making any changes to the existing implementation. The extensibility point will expose the operations of service to other components which will get chance to act upon service requests.

I considered few design approaches to accomplish this, however I found most of the approaches to be intrusive to existing implementation. I was looking for something which will be loosely coupled to the existing service implementation and really be like plug-and-play, without much code changes.

First obvious thought was to look at IoC(Inversion of Control) and DI(Dependency Injection) along with WCF extensibility points. After looking all the available WCF extensibility points it was easy to zero down on Parameter Inspector (IParameterInspector) as it gives access to the operation name and parameters. If we know the operation being called along with parameters and all the extensions implemented for that specific service, it would be just matter of loading the extensions and calling the operation.

When you look at IoC/DI space there are few seemingly overlapping options from Microsoft itself, like Unity application block from P&P, Managed add-in framework (MAF) in System.AddIn namespace and the latest entrant Managed Extensibility Framework(MEF). At high level, all of these are composition engines, however MEF looked like specialized IoC container with added bells and whistles around DI. MEF is optimized around ‘discovery of unknown parts’ rather than just ‘registration of known parts’, this is what made MEF an interesting option for the problem I was trying to solve.  Another consideration was that MEF is bundled with .Net Framework 4.0, so no more libraries to update and move around. There is a nice post about Ten Reasons to use the Managed Extensibility Framework.

After little bit playing around with MEF, following looked like the emerging pattern for the problem I was trying to solve.


 WCFandMEF


I defined an attribute(named ‘ServiceOperationExtensibility’) which implements IOperationBehavior interface and adds IParameterInspector DispatchBehavior. This attribute can be applied to an operation which needs to be exposed as extensibility point as shown below.

   1: [OperationContract]
   2: [ServiceOperationExtensibility]
   3: string OperationA(int param1, string param2);

A class implementing IParameterInspector (named ‘ExtensibilityInspector’) will accept the service contract type as constructor parameter.

   1: ExtensibilityInspector extensibilityInspector = new ExtensibilityInspector(operationDescription.DeclaringContract.ContractType);
   2: dispatchOperation.ParameterInspectors.Add(extensibilityInspector);

The ExtensibilityInspector simply gets instance of ExtensibilityManager and passes the service contract type, operation name and arguments in ‘BeforeCall’ method of IParameterInspector interface.

   1: public object BeforeCall(string operationName, object[] inputs)
   2: {
   3:     ExtensibilityManager.Instance.InvokeExtension(this.ServiceContractType, operationName, inputs);
   4:     return null;
   5: }

The ExtensibilityManager is responsible for discovering and loading the extension components and calling the operation. The extension components needs to implement contract of service being extended. The component need to decorate the class with MEF ‘Export’ attribute, this attribute would allow it to be discovered by MEF catalog.

   1: [Export(typeof(ProductService.IProductService))]
   2: public class ProductServiceExtension1:ProductService.IProductService
   3: {
   4:     //Implementation removed for brevity
   5: }

The ExtensibilityManager creates MEF catalog from assemblies present in designated directory. So the extension components need to be simply dropped in to designated directory(I have named this directory ‘Extensions’).

   1: private void Compose()
   2: {
   3:     var Catalog = new AggregateCatalog();
   4:     Catalog.Catalogs.Add(new DirectoryCatalog(@".\Extensions"));
   5:     this.Container = new CompositionContainer(Catalog);
   6:     this.Container.ComposeParts(this);            
   7: }

InvokeExtension method of ExtensibilityManager created instance of MEF ImportDefinition based on the passed service contract type. It calls TryGetExports method on the previously created container to get all the extensions of specific type.

   1: public void InvokeExtension(Type contractType, string operationName,object[] arguments)
   2: {
   3:     ImportDefinition importDefinition = new ImportDefinition(i => i.ContractName.Equals(contractType.FullName), contractType.FullName, ImportCardinality.ZeroOrMore, false, false);
   4:     AtomicComposition atomicComposition = new AtomicComposition();
   5:     IEnumerable<Export> extensions = null;
   6:  
   7:     bool exportDiscovery = this.Container.TryGetExports(importDefinition, atomicComposition, out extensions);
   8:     
   9:     if (extensions != null && extensions.Count<Export>() > 0)
  10:     {
  11:         foreach (Export extensionExport in extensions)
  12:         {
  13:             //ToDo: spawn a thread and do work there instead of doing it on the calling thread
  14:             contractType.InvokeMember(operationName, System.Reflection.BindingFlags.InvokeMethod, null, extensionExport.Value, arguments);
  15:         }
  16:     }
  17: }

After getting the extensions, we can invoke the operation on each of the extension components. Please note that in this sample I have directly called InvokeMember operation on the type instance, in production code you will spawn a thread instead of doing it on the calling thread.

Overall this turned out to be a good solution, though there is a space for improvement to make it more fault tolerant and scalable. Depending upon your scenario you need to build good security around the extensibility points and components, which I have completely omitted here.

The sample code can be downloaded from following link. The sample service(named ‘IProductService’) is hosted in IIS, you can use WCFTestClient to invoke the operations. I have added one extension component in the solution which simply writes an entry to windows event log on invocation of the operation.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

patelsan
Web Developer
United States United States
No Biography provided

Comments and Discussions

 
GeneralWhat are the benefits using MEF with WCF PinmemberNils B7-Jun-11 1:49 
GeneralFormatting PinmentorKunalChowdhury8-Sep-10 1:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 8 Sep 2010
Article Copyright 2010 by patelsan
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid