8

After doing some research on MEF I came across the CreationPolicy.Shared property which according to MSDN:

Specifies that a single shared instance of the associated ComposablePart will be created by the CompositionContainer and shared by all requestors.

Sounds good as long as I always ensure that one and only one container ever accesses the class that I export with this policy. So how do I go about ensuring that only one container ever accesses my exported type? Here is my scenario:

I have a Windows service that needs to tap into a singleton-like class for some in-memory data. The data is non-persistent so I want it to be freshly created whenever the service starts up but it serves no purpose once the service is stopped. Multiple threads in my service will need to read and write to this object in a thread-safe fashion so my initial plan was to inherit from ConcurrentDictionary to ensure thread safe operations against it.

The threads that will be tapping into this class all inherit from a single abstract base class, so is there a way to have this class (and only this class) import it from MEF and have this work the way I want?

thanks for any tips you may have, I'm newish to MEF so I'm still learning the ins and outs

BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
snappymcsnap
  • 2,050
  • 2
  • 29
  • 53
  • 1
    I've used NInject with its "as singleton" mode for a binding to great effect. Just be careful to keep whatever it is MEF is providing that way thread-safe (no state or funny side effects). – bluevector Jun 15 '12 at 19:25
  • @jonnyGold Thanks, I have not used Ninject before...does it piggyback on MEF at all or is it its own unique DI framework? – snappymcsnap Jun 15 '12 at 21:20
  • 1
    It is its own framework. You can grab it through nuget and there are specializations for MVC and WCF. My favorite thing about it is that the bindings are declared in code, so you can't make a type-matching mistake. Or a typo, for that matter. Also, the contextual bindings are really powerful. – bluevector Jun 18 '12 at 12:32

2 Answers2

1

If it absolutely must be a singleton amongst different containers, you could use a private constructor and expose a static Instance property, as if it were a "classic" non-container-managed singleton. Then in the composition root, use ComposeExportedValue to register it with the container:

container.ComposeExportedValue(MySingleton.Instance);
default.kramer
  • 5,943
  • 2
  • 32
  • 50
  • not quite, if possible I would like to only expose it to a single container and the the MEF framework will ensure it is a singleton by default. If this isn't possible however then I see no advantage to using MEF for this in the first place – snappymcsnap Jun 15 '12 at 21:07
  • 1
    I'm not sure I understand exactly what you're asking. You should ensure that only one container exists. Then `CreationPolicy.Shared` will result in a singleton. Are you thinking about creating multiple containers? Because that would be atypical. – default.kramer Jun 18 '12 at 14:04
0

You could always use the Lazy type since it blocks other threads as described in this blog post: http://geekswithblogs.net/BlackRabbitCoder/archive/2010/05/19/c-system.lazylttgt-and-the-singleton-design-pattern.aspx

kappasims
  • 124
  • 9