Search code examples
c#-4.0inversion-of-controlmef

Specify RequiredCreationPolicy for non-Attributed Imports


I have an IoC wrapper that uses MEF as it's DI container, an applicable snippet of the wrapper is shown below.

public static bool TryGetComponent<T>(out T component) 
{
    CompositionContainer container = RetrieveContainer();

    T retrievedComponent = container.GetExportedValueOrDefault<T>();
    if (retrievedComponent.Equals(default(T)))
    {
        component = default(T);
        return false;
    }

    component = retrievedComponent;

    return true;
}

Most of the exported components in the CompositionContainer specify a CreationPolicy of "Any".

[PartCreationPolicy(CreationPolicy.Any)]

For types that I create I can easily use the following import attribute to get MEF to serve the exported types as NonShared instances.

[Import(RequiredCreationPolicy = CreationPolicy.NonShared)]

However, since my IoC wrapper must also be used by classes that do not use MEF or any of its Import attributes and must use my IoC API to obtain instances exported types. I need a way to specify the CreationPolicy when I programmatically use the CompositionContainer to GetExports and GetExportedValues. Is this even possible without using import attributes?


Solution

  • If you really want to query the container exactly like as if you had a ImportAttribute with RequiredCreationPolicy=NonShared then try creating your own custom ContractBasedImportDefinition. One of the parameters for to the contructor is a CreationPolicy that represents the required creation policy. Something like:

    container.GetExports(new ContractBasedImportDefinition(
        AttributedModelServices.GetContractName(type),
        AttributedModelServices.GetTypeIdentity(type),
        null,
        ImportCardinality.ZeroOrMore,
        false,
        false,
        CreationPolicy.NonShared));
    

    Of course you can adjust the parameters as necessary but this will get you moving in the right direction and will cause the container to create NonShared versions of any part that is marked as Any (which is the default).