Search code examples
wpfserviceprismmef

Prism v4, MEF service


I have a WPF windows application that uses the ms ribbon control for the menu. In my infrastructure project I want to have a shared service that will be referenced in all modules. Each module will then use that service to define what menu items should be displayed for the module.

I read this Prism+MEF: delayed a service export from prism-module but can't get my other modules to recognize the service.

The service

namespace Infrastructure
{
    [ModuleExport("InfModule", typeof(InfModule), InitializationMode = InitializationMode.WhenAvailable)]
    [PartCreationPolicy(CreationPolicy.Shared)]
    public class InfModule : IModule
    {
        [Export(typeof(IMenuService))]
        public IMenuService MenuService { get; private set; }

        public void Initialize()
        {
            MenuService = new MenuService();

            MenuService.AddItem("test");
        }
    }
}

The module

namespace Classic
{
    [ModuleExport("Classic", typeof(Classic), InitializationMode = InitializationMode.WhenAvailable)]
    [ModuleDependency("InfModule")]
    public class Classic : IModule
    {
        private IRegionManager _regionManager;

        [Import(typeof(IMenuService))]
        private IMenuService menuService { get; set; }

        [ImportingConstructor]
        public Classic(IRegionManager regionManager)
        {
            this._regionManager = regionManager;

            // This shows as true
            Debug.WriteLine(menuService == null);
        }

        public void Initialize()
        {
            _regionManager.RegisterViewWithRegion("RibbonRegion", typeof(Views.RibbonTabMenu));

            // This shows as true
            Debug.WriteLine(menuService == null);
        }
    }
}

I would have expected one of the debug lines to output as false since its imported. Any idea's what I'm missing?


Solution

  • Property imports will never be set while running the constructor, since you can't set properties on an object until it's constructed.

    The other problem is that in InfModule, you are setting the exported value too late. MEF only looks at the value for an export once, after that it caches the value and doesn't call the getter again. In this case it is getting the export before Initialize() is called. The logic to set the export needs to either run from the constructor or from code in the property getter.