Search code examples
c#mefcomposition

How to fulfill System.Composition MEF ImportingConstructor with an instance


I'm using MEF (System.Composition from nuget) + Common.Logging and have classes that call ILog, e.g.,

[Export(typeof(ITranslator))]
public class ATranslator : BaseTranslator
{
    [ImportingConstructor]
    public ATranslator(ILog log)
    {
...
    }

The logger instance is available from Common.Logging via log = LogManager.GetLogger<ITranslator>(); but how do I plugin this into my composition container?

        var container = new ContainerConfiguration()
            .WithAssembly(typeof(ITranslator).Assembly)
            .CreateContainer();            
        container.SatisfyImports(this);

so that I can

    [ImportMany]
    private IEnumerable<ITranslator> Translators { get; set; }

without

System.Composition.Hosting.CompositionFailedException : No export was found for the contract 'ILog' -> required by import 'log' of part 'ATranslator' -> required by import 'item' of part 'ITranslator[]' -> required by initial request for contract 'IEnumerable { IsImportMany = True }'


Solution

  • Maybe you can try to do the export to ILog as a property in other class?

    public class LogExporter
    {
        [Export(typeof(ILog))]
        public ILog Log
        {
            return LogManager.GetLogger<ITranslator>();
        }
    }
    

    Alternatively you can try to do it using ComposeExportedValue Method with code instead of attributes:

    container.ComposeExportedValue<ILog>(LogManager.GetLogger<ITranslator>());