Prism: MEF2 by Microsoft.Composition

Created on 22 Aug 2016  路  13Comments  路  Source: PrismLibrary/Prism

Hello, Prism should use new version of MEF Framework from NuGet "Microsoft.Composition" due to better performance.

Here is performance comparion of IoC containers:
http://www.palmmedia.de/blog/2011/8/30/ioc-container-benchmark-performance-comparison

MEF2 many times faster than current .NET implementation.

wontfix

Most helpful comment

I understand your point but considering that MEF2 is THE ONLY officially supported IOC in Xamarin and UWP it makes MEF2 special case.
If I want to contribute the code, assuming code above is not good, what would be my steps?

All 13 comments

We will not be adding any new MEF support to Prism. What we have is all there is going to be.

.. and is there only for backwards compatibility with previous Prism versions so people can upgrade without having to rewrite their whole application.

But nothing keeps you from forking and implementing MEF2 yourself.

Duplicate of #375

I have implemented MEF2 bootstraper
`
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.ServiceLocation;
using Prism.Logging;
using Prism.Modularity;
using Prism.Regions;
using System.Composition.Convention;
using System.Composition.Hosting;
using System.Composition;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using Prism;
using Prism.Events;
using Prism.Regions.Behaviors;
using Telerik.Windows.Controls;

namespace TelerikShell
{
public abstract class Mef2Bootstrapper : Bootstrapper
{
[Export]
public CompositionHost Container { get; set; }
protected ContainerConfiguration ContainerConfig { get; set; }

    protected ConventionBuilder Builder { set; get; }

    protected Mef2Bootstrapper()
    {
        ContainerConfig = new ContainerConfiguration();
        ConfigureConventions();
        ContainerConfig.WithAssemblies(AppDomain.CurrentDomain.GetAssemblies(), Builder);
    }

    protected override void InitializeModules()
    {
        this.Container.GetExport<IModuleManager>().Run();
    }

    protected virtual void ConfigureConventions()
    {
        Builder = new ConventionBuilder();

        Builder.ForType<EmptyLogger>().ExportInterfaces().Shared();
        Builder.ForType<ModuleCatalog>().ExportInterfaces().Shared();
        Builder.ForType<Mef2ServiceLocator>().ExportInterfaces().Shared();
        Builder.ForType<RegionAdapterMappings>().Export().Shared();

        Builder.ForType<SelectorRegionAdapter>().Export().ExportInterfaces().Shared();
        Builder.ForType<ItemsControlRegionAdapter>().Export().ExportInterfaces().Shared();
        Builder.ForType<ContentControlRegionAdapter>().Export().ExportInterfaces().Shared();

        Builder.ForType<RegionManager>().Export().ExportInterfaces().Shared();
        Builder.ForType<EventAggregator>().ExportInterfaces().Shared();
        Builder.ForType<RegionNavigationJournalEntry>().ExportInterfaces().Shared();
        Builder.ForType<RegionViewRegistry>().ExportInterfaces().Shared();
        Builder.ForType<RegionNavigationJournal>().ExportInterfaces().Shared();
        Builder.ForType<RegionNavigationContentLoader>().ExportInterfaces().Shared();
        Builder.ForType<RegionBehaviorFactory>().ExportInterfaces().Shared();
        Builder.ForType<ModuleManager>().ExportInterfaces().Shared();
        Builder.ForType<ModuleInitializer>().ExportInterfaces().Shared();


        Builder.ForType<AutoPopulateRegionBehavior>().Export().ExportInterfaces();
        Builder.ForType<BindRegionContextToDependencyObjectBehavior>().Export().ExportInterfaces();
        Builder.ForType<ClearChildViewsRegionBehavior>().Export().ExportInterfaces();
        Builder.ForType<DelayedRegionCreationBehavior>().Export().ExportInterfaces();
        Builder.ForType<RegionActiveAwareBehavior>().Export().ExportInterfaces();
        Builder.ForType<RegionManagerRegistrationBehavior>().Export().ExportInterfaces();
        Builder.ForType<RegionMemberLifetimeBehavior>().Export().ExportInterfaces();
        Builder.ForType<SelectorItemsSourceSyncBehavior>().Export().ExportInterfaces();
        Builder.ForType<SyncRegionContextWithHostBehavior>().Export().ExportInterfaces();
    }

    protected override void ConfigureServiceLocator()
    {
        var serviceLocator = Container.GetExport<IServiceLocator>();
        ServiceLocator.SetLocatorProvider((() => serviceLocator));
    }

    protected override RegionAdapterMappings ConfigureRegionAdapterMappings()
    {
        var instance = Container.GetExport<RegionAdapterMappings>();
        instance.RegisterMapping(typeof(Selector), Container.GetExport<SelectorRegionAdapter>());
        instance.RegisterMapping(typeof(ItemsControl), Container.GetExport<ItemsControlRegionAdapter>());
        instance.RegisterMapping(typeof(ContentControl), Container.GetExport<ContentControlRegionAdapter>());
        instance.RegisterMapping(typeof(RadPaneGroup), Container.GetExport<RadPaneGroupRegionAdapter>());
        return instance;
    }

    public override void Run(bool runWithDefaultConfiguration)
    {
        this.ModuleCatalog = this.CreateModuleCatalog();
        this.ConfigureModuleCatalog();
        this.Container = ContainerConfig.CreateContainer();
        Mef2ServiceLocator.Host = Container;
        this.ConfigureServiceLocator();
        this.ConfigureViewModelLocator();
        this.ConfigureRegionAdapterMappings();
        this.ConfigureDefaultRegionBehaviors();
        this.RegisterFrameworkExceptionTypes();

        this.Shell = this.CreateShell();

        if (this.Shell != null)
        {
            RegionManager.SetRegionManager(this.Shell, this.Container.GetExport<IRegionManager>());      
            RegionManager.UpdateRegions();
            this.InitializeShell();
        }

        var exports = Container.GetExports<IModuleManager>();
        if (exports != null && exports.Any())
        {
            this.InitializeModules();
        }

        var modules = Container.GetExports<IModule>();
        foreach (var module in modules)
        {
            module.Initialize();
        }
    }
}

}
`

@brianlagunas This is rather unfortunate. Could you provide any rationale for this decision?
I think you are making a mistake not supporting IOC that is forward runner in cross platform world. If contributed code is not up to standards it could be improved but completely ignoring new platform is irresponsible.

We can not add every single IoC container (if you want to discuss that MEF is actually an IoC container) and provide support for them given our limited time and resources (we all do this in our spare time). Like mentioned before, nothing prevents people from forking and providing support themselves.

Sending a onetime PR with an implementation is only the first step. The actual work is keeping thinks up to date, fixing bugs, uploading new packages, ... There are more urgent things to cover than adding in Mef2.

I understand your point but considering that MEF2 is THE ONLY officially supported IOC in Xamarin and UWP it makes MEF2 special case.
If I want to contribute the code, assuming code above is not good, what would be my steps?

There are a number of other containers that are supported by their respective teams that Prism already has NuGets for. MEF2 is not an IoC container. I will not be adding MEF support to the official Prism library, because I do not want to support it and I do not believe it should be used for internal dependency construction. You are more than welcome to create your own MEF2 extension project on GitHub and publish it to Nuget under your project name. You can use one of the current IoC implementations as a reference. I am sure your community will appreciate your contribution.

What are your plans for IOC in Windows 10 UWP, and Xamarin Forms?

We really haven't touched UWP since we ported it from the original MS P&P team. It is my lowest priority. Xamarin.Forms already has a number of IoC containers supported. You can check out the documentation to see what is support right now.

http://prismlibrary.readthedocs.io/en/latest/NuGet-Packages/

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

brianlagunas picture brianlagunas  路  5Comments

topfunet picture topfunet  路  5Comments

brianlagunas picture brianlagunas  路  4Comments

joacar picture joacar  路  6Comments

tiagodenoronha picture tiagodenoronha  路  4Comments