eWorld.UI - Matt Hawley

Ramblings of Matt

MEF + Factories

November 27, 2008 13:47 by matthaw

Lately I've been really digging into MEF and have been looking at it's pros & cons, ease of use, extensibility, and the simple DI container that it can provide. I'm not going to give an overview of MEF, as others have done so already. What I am here to show off is a concept that may prove useful for some applications. Many of us use a DI container in very simplistic ways, as well as registering injection strategies during type resolution. If you have no needs of this latter, MEF is very simple and easily fits into your current architecture by not having to change anything but decorating things. For example:

   1:  public interface IUserService { }
   2:   
   3:  [Export(typeof(IUserService))]
   4:  [CompositionOptions(CreationPolicy = CreationPolicy.Factory)]
   5:  public class UserService : IUserService { }
   6:   
   7:  [Export]
   8:  public class UserController {
   9:     [ImportingConstructor]
  10:     public UserController(IUserService userService) { }
  11:  }

At MEF's simplistic nature, you see that during construction, our exported services are being imported for us, but only because we don't care about it's construction and assume that generic construction will work. So when we call resolve UserController using MEF, it'll create and inject a new instance of UserService for us.

 

Now, say we have a need where the construction of IUserService needs to go through a factory. For instance, maybe IUserService is a WCF endpoint, and you have custom logic built into properly constructing the proxy endpoint. Well, MEF can solve this issue for you by exporting methods, but what you have to do is ultimately change your code and have 2 constructors.

   1:  public interface IUserService { }
   2:   
   3:  // in your application
   4:  [Export(typeof(IUserService))]
   5:  public IUserService ConstructUserService() { return ... }
   6:   
   7:  [Export]
   8:  public class UserController {
   9:     [ImportingConstructor]
  10:     public UserController([Import(typeof(IUserService))] Func<IUserService> serviceMethod)
  11:         : this(serviceMethod())
  12:     { }
  13:   
  14:     public UserController(IUserService userService) { }
  15:  }

As you can see, it's not that nice. We need both constructors because one is used in production and one is used for testability. It ultimately leads to a lot of confusion as to why we need it. So, with that in mind, I set out to determine how this pattern could be achieved using MEF, but also provide a seamless transition from a DI world to MEF. Enter, FactoryPartCatalog:

   1:  public class FactoryPartCatalog<T> : ComposablePartCatalog {
   2:     public FactoryPartCatalog(Func<Type, T> resolutionMethod) { }
   3:     public FactoryPartCatalog(Assembly assembly, Func<Type, T> resolutionMethod) { }
   4:     public FactoryPartCatalog(IEnumerable<Type> types, Func<Type, T> resolutionMethod) { }
   5:   
   6:     public override IQueryable<ComposableDefinition> Parts { get { return ... } }
   7:  }

When we use this in our application, it brings back the simplicity of MEF. What it's doing during construction is looking through the assembly (first two constructors) to find all interfaces that implement type T. The interfaces that it finds will be created into ComposablePart's for MEF's container to utilize. Ultimately, when GetExportedObject<T> is called, it'll execute the resolution method you specified passing in the Type that was requested.

 

As you can see below, we're using a AggregatingComposablePartCatalog adding our new FactoryPartCatalog and AttributedAssemblyPartCatalog. We've told FactoryPartCatalog to look through the current assembly for all interfaces that derive from IService. Upon construction injection by MEF, it'll find that it's requesting an export of IUserService, find it in the FactoryPartCatalog, and call GetService(Type) to get it's instance.

   1:  public interface IService { }
   2:  public interface IUserService : IService { }
   3:   
   4:  [Export]
   5:  public class UserController {
   6:     [ImportingConstructor]
   7:     public UserController(IUserService userService) { }
   8:  }
   9:   
  10:  // in your application
  11:  private void Compose() {
  12:     var catalog = AggregatingComposablePartCatalog();
  13:     catalog.Catalogs.Add(new AttributedAssemblyPartCatalog(Assembly.GetExecutingAssembly()));
  14:     catalog.Catalogs.Add(new FactoryPartCatalog<IService>(GetService);
  15:     var container = new CompositionContainer(catalog);
  16:     container.AddPart(this);
  17:     container.Compose();
  18:  }
  19:   
  20:  public IService GetService(Type type) { return ... }

Now, there's a lot more code behind the scenes that is required to get a new Part Catalog up and running, but I'll leave that for you to check out in the downloadable source. As this is purely a proof of concept, I'm sure there's more simplifications or additions that can be added, but for getting this running out of the box in this manner, it works great!

 

kick it on DotNetKicks.com


Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: .NET | Development | MEF
Actions: E-mail | Permalink | Comments (20) | Comment RSSRSS comment feed

Comments

November 29. 2008 04:13

Pingback from weblogs.asp.net

MEF + Factories - eWorld.UI - Matt Hawley

weblogs.asp.net

November 30. 2008 16:46

Pingback from blogs.msdn.com

My Technobabble : Export Providers and Custom factories with MEF

blogs.msdn.com

November 30. 2008 17:26

Pingback from feeds.feedburner.com

Export Providers and Custom factories with MEF - Glenn Block

feeds.feedburner.com

November 30. 2008 17:43

Pingback from codebetter.com

Export Providers and Custom factories with MEF - Glenn Block

codebetter.com

December 2. 2008 19:15

Pingback from taccato.com

Export Providers and Custom factories with MEF - taccato! trend tracker, cool hunting, new business ideas

taccato.com

April 21. 2009 18:01

hi all.
thank too the apple.

ankara lazer epilasyon

April 29. 2009 14:09

MEF is very nice and above all very simple to use as stated in the post.Worth trying.

Refrigerator Water Filter

May 12. 2009 05:42

Thanks a lot for this scripot.I have been looking for it for a long time

Where

May 12. 2009 05:51

I have been using MEF for quite a sometime now and really Its worth using .I am happy with what I have seen of it so far

Green Tea Diet Pills

May 20. 2009 19:53

I think MEF is a great interface to use and is one of the most user friendly.

Luggage Sets

May 28. 2009 08:12

I was looking for this thanks for the detailed Information and the download link.

Scotsman Ice Machine

June 4. 2009 06:50

CAn MEf be used with .net applications - Sam

medical billing training

June 8. 2009 04:45


Gotta bookmark this post. Thanks a lot. Smile

new york hardmoney lenders

June 24. 2009 04:14

a sometime now and really Its worth using .I am happy with what I have seen of it so far

Green Tea Diet Pills

fire science degree

June 24. 2009 04:15

its a great interface to use and is one of the most user friendly.

online fire degrees

June 24. 2009 04:15

I was looking for this thanks for the detailed Information and the download link.

law degree

June 24. 2009 04:15

taccato! trend tracker, cool hunting, new business ideas

online legal degree

June 24. 2009 04:16

Information and the download link.

legal studies degree

June 26. 2009 11:23

Thanks for this post! I now know some new ideas on MEF. Thanks for all the links.

France Cheap Tickets

July 3. 2009 04:41

nice post.i have been following this blog

Lap band

Add comment


 

  Country flag

[b][/b] - [i][/i] - [u][/u]- [quote][/quote]



Live preview

July 3. 2009 21:34



Copyright © 2000 - 2009 , Excentrics World