/// <summary> /// Convenience constructor method that creates a new <see cref="MefSingletonComposer"/>, that is /// created from a new <see cref="ConventionBuilder"/>, for the given /// <paramref name="exportType"/> /// type, and is <c>Shared</c>. The returned object composes only for the single type. /// Notice also, this class extends <see cref="Composer{TTarget}"/>, and this by /// default sets <see cref="Composer{TTarget}.ComposeExceptionPolicy"/> to /// <see cref="ComposerExceptionPolicy.ThrowNone"/>. /// </summary> /// <param name="exportType">The single export type for the composer.</param> /// <param name="onlyDerivedTypesExclusively">Allows you to specify only /// <see cref="ConventionBuilder.ForTypesDerivedFrom"/> (if true), only /// <see cref="ConventionBuilder.ForType"/> (if false), or both (if null). /// If the type is abstract then ForType is not applied.</param> /// <param name="disposeCompositionHostsWithThis">Specifies how all created /// <see cref="CompositionHost"/> instances are handled when this object is disposed: notice /// that this defaults to true --- when disposed, the contained exports may be disposed. If /// not disposed, the references are simply dropped.</param> /// <param name="disposeProvidersWithThis">Specifies how added PROVIDERS are handled when /// this object is disposed: notice that this defaults to true.</param> /// <param name="handleNewExports">Optional argument for the result.</param> /// <returns>Not null.</returns> public static MefSingletonComposer ForSingleType( Type exportType, bool?onlyDerivedTypesExclusively, bool disposeCompositionHostsWithThis = true, bool disposeProvidersWithThis = true, Func <List <object>, IReadOnlyList <object>, Action> handleNewExports = null) { if (exportType == null) { throw new ArgumentNullException(nameof(exportType)); } return(new MefSingletonComposer( exportType.AsSingle(), MefComposerHelper.CreateDefaultConventions(exportType, onlyDerivedTypesExclusively), disposeCompositionHostsWithThis, disposeProvidersWithThis, handleNewExports)); }
public static void Main(string[] args) { Console.WriteLine("Begin ..."); BasicContainer target = new BasicContainer(); // Our composition target Console.WriteLine($"New BasicContainer: {target}"); using (ContainerComposer <IContainerBase> composer = new ContainerComposer <IContainerBase>(() => target)) { // Composer // Discover Assemblies in our Program CodeBase, // and search for any Exported IComposerParticipant<IContainerBase> participants: // (crude implementation will simply load all Assemblies here and look for Exports in every one) string codeBase = new Uri(typeof(Program).Assembly.GetName().CodeBase) .LocalPath; codeBase = Path.GetDirectoryName(codeBase); foreach (string filePath in Directory.EnumerateFiles( codeBase, "*.dll", SearchOption.TopDirectoryOnly)) { // MefComposerHelper loads any Exports from the assembly: composer.ParticipateRange( MefComposerHelper.GetInstances <IComposerParticipant <IContainerBase> >( Assembly.LoadFrom(filePath))); } Console.WriteLine($"Composer: {composer}"); Console.WriteLine("Compose ..."); // Tracing is not set verbose until here, because the above // MEF helper methods also create Composer instances while // fetching Exports ... The console will be cluttered // with verbose traces from each Assembly above ... Program.configureTracing(); composer.Compose(); // Compose } Console.WriteLine($"BasicContainer: {target}"); Console.WriteLine(" ... All Registered Service Types:"); foreach (Type serviceType in target.GetRegisteredServiceTypes()) { Console.WriteLine($" {serviceType.FullName}"); } Console.WriteLine("Done"); Console.ReadKey(); }