Shared Instance¶
What does this mean ?¶
Classic MEF's CreationPolicy.Shared controls exported part instances created through composition. It does not make the C# constructor inaccessible or establish a process-wide singleton. Creation policies operate within a composition container.
What can happen ?¶
Calling new bypasses MEF construction and import fulfillment. Consumers may receive different caches or configuration state when they expected one shared service. This is primarily a lifecycle defect, not automatically a security vulnerability. Explicit construction can still be appropriate for isolated unit tests or intentionally independent objects.
Recommendation¶
Resolve an application-owned shared export through the same configured container. Scope and dispose that container deliberately. Sharing does not make mutable state thread-safe, and user-specific data must not accidentally become shared across requests. A separate dependency injection container requires its own registration; an MEF attribute does not configure it.
Sample Code¶
Use System.ComponentModel.Composition and .Hosting namespaces. Both alternatives assume this export:
public interface IClock { }
[Export(typeof(IClock))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class Clock : IClock { }
Bypasses the expected shared lifetime:
IClock first = new Clock();
IClock second = new Clock();
Resolves through one container:
using (var catalog = new TypeCatalog(typeof(Clock)))
using (var container = new CompositionContainer(catalog))
{
IClock first = container.GetExportedValue<IClock>();
IClock second = container.GetExportedValue<IClock>();
System.Diagnostics.Debug.Assert(object.ReferenceEquals(first, second));
}
Regression test: assert reference equality in the same container and independent instances in separate containers. Add a test for any required imports and for cleanup at container disposal; a reference-equality assertion alone does not verify the full lifecycle.