Issue with downloading modules

Topics: Prism v4 - Silverlight 4
Nov 15, 2010 at 4:50 AM
Edited Nov 15, 2010 at 4:54 AM

Hi,

I'm using Prism 4 with MEF. I have my bootstrapper inheriting from MefBootstrapper as follows

public class Bootstrapper : MefBootstrapper
    {
        protected override DependencyObject CreateShell()
        {
            var shell = new MainPage();
            Application.Current.RootVisual = shell;
            shell.Container = Container;
            shell.AggregateCatalog = AggregateCatalog;
            return shell;
        }

        protected override void ConfigureAggregateCatalog()
        {
            base.ConfigureAggregateCatalog();

            AggregateCatalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
        }

        protected override void ConfigureContainer()
        {
            base.ConfigureContainer();
            base.Container.ComposeParts(new MyModuleInitializer());
        }

        protected override IModuleCatalog CreateModuleCatalog()
        {
            var localModule1 = new ModuleInfo
            {
                Ref = "LocalModule1.xap",
                ModuleName = "LocalModule1",
                ModuleType = "LocalModule1.Module, LocalModule1, Version=1",
                InitializationMode = InitializationMode.OnDemand
            };
            var moduleCatalog = new ModuleCatalog(new[] { localModule1} );
            return moduleCatalog;
        }
    }

My project structure is a follows

  • Web
    • Main Host application
      • Has a region Region2 defined in Main.xaml
    • Loca Module 1 application
      • It registers itself with Region2 in the Initialize of its module.

My Local Module 1 is as follows

MainPage.xaml.cs

[Export]
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
        }

        [Import]
        public MainViewModel Model
        {
            set { DataContext = value; }
        }
    }

MainViewModel

[Export]
    public class MainViewModel : INotifyPropertyChanged
    {
        private string _text;

        public MainViewModel()
        {
            Text = "Local Module 1";
        }
        public string Text
        {
            get { return _text; }
            set
            {
                _text = value;
                OnPropertyChanged("Text");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

Module

[ModuleExport(typeof(Module))]
    public class Module : IModule
    {
        private IRegionManager _regionManager;

        [ImportingConstructor]
        public Module(IRegionManager regionManager)   
        {   
            _regionManager = regionManager;   
        }  

        public void Initialize()
        {
            _regionManager.RegisterViewWithRegion("Region2", typeof (MainPage));
        }
    }

Now in the MainPage of my host application I have a button, clicking on which I download the LocalModule1 as follows

public partial class MainPage : UserControl
    {
        private IModuleCatalog _moduleCatalog;
        private IModuleManager _moduleManager;

        public MainPage()
        {
            
            InitializeComponent();
        }


        private void LoadRemotModule()
        {
            _moduleCatalog = Container.GetExportedValue<IModuleCatalog>();
            _moduleManager = Container.GetExportedValue<IModuleManager>();

            var moduleInCatalog = _moduleCatalog.Modules.Single(m => m.ModuleName.ToLower() == "localmodule1");
            if(moduleInCatalog.State == ModuleState.NotStarted)
                _moduleManager.LoadModule(moduleInCatalog.ModuleName);
        }

        void deploymentCatalog_DownloadCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            if (e.Error != null)
                throw e.Error;
        }

        public CompositionContainer Container { get; set; }

        public AggregateCatalog AggregateCatalog { get; set; }

        private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            LoadRemotModule();
        }
    }

 When _moduleManager.LoadModule(moduleInCatalog.ModuleName) is called I get the below error.

An exception occurred while initializing module 'LocalModule1'.
    - The exception message was: The composition remains unchanged. The changes were rejected because of the following error(s): The composition produced multiple composition errors, with 15 root causes. The root causes are provided below. Review the CompositionException.Errors property for more detailed information.

1) Change in exports prevented by non-recomposable import 'Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleInitializer..ctor (Parameter="downloadedPartCatalogs", ContractName="Microsoft.Practices.Prism.MefExtensions.Modularity.DownloadedPartCatalogCollection")' on part 'Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleInitializer'.

2) Change in exports prevented by non-recomposable import 'Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleManager.MefXapModuleTypeLoader (ContractName="Microsoft.Practices.Prism.MefExtensions.Modularity.MefXapModuleTypeLoader")' on part 'Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleManager'.

3) Change in exports prevented by non-recomposable import 'Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleManager..ctor (Parameter="moduleInitializer", ContractName="Microsoft.Practices.Prism.Modularity.IModuleInitializer")' on part 'Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleManager'.

4) Change in exports prevented by non-recomposable import 'Microsoft.Practices.Prism.MefExtensions.Modularity.MefXapModuleTypeLoader..ctor (Parameter="downloadedPartCatalogs", ContractName="Microsoft.Practices.Prism.MefExtensions.Modularity.DownloadedPartCatalogCollection")' on part 'Microsoft.Practices.Prism.MefExtensions.Modularity.MefXapModuleTypeLoader'.

5) Change in exports prevented by non-recomposable import 'Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleInitializer..ctor (Parameter="downloadedPartCatalogs", ContractName="Microsoft.Practices.Prism.MefExtensions.Modularity.DownloadedPartCatalogCollection")' on part 'Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleInitializer'.

6) Change in exports prevented by non-recomposable import 'Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleManager.MefXapModuleTypeLoader (ContractName="Microsoft.Practices.Prism.MefExtensions.Modularity.MefXapModuleTypeLoader")' on part 'Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleManager'.

7) Change in exports prevented by non-recomposable import 'Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleManager..ctor (Parameter="moduleInitializer", ContractName="Microsoft.Practices.Prism.Modularity.IModuleInitializer")' on part 'Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleManager'.

8) More than one export was found that matches the constraint '((exportDefinition.ContractName == "Microsoft.Practices.Prism.Regions.RegionAdapterMappings") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "Microsoft.Practices.Prism.Regions.RegionAdapterMappings".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))'.

Resulting in: Cannot set import 'Microsoft.Practices.Prism.MefExtensions.Regions.Behaviors.MefDelayedRegionCreationBehavior..ctor (Parameter="regionAdapterMappings", ContractName="Microsoft.Practices.Prism.Regions.RegionAdapterMappings")' on part 'Microsoft.Practices.Prism.MefExtensions.Regions.Behaviors.MefDelayedRegionCreationBehavior'.
Element: Microsoft.Practices.Prism.MefExtensions.Regions.Behaviors.MefDelayedRegionCreationBehavior..ctor (Parameter="regionAdapterMappings", ContractName="Microsoft.Practices.Prism.Regions.RegionAdapterMappings") -->  Microsoft.Practices.Prism.MefExtensions.Regions.Behaviors.MefDelayedRegionCreationBehavior -->  AssemblyCatalog (Assembly="Microsoft.Practices.Prism.MefExtensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")

9) Change in exports prevented by non-recomposable import 'Microsoft.Practices.Prism.MefExtensions.Regions.MefTabControlRegionAdapter..ctor (Parameter="regionBehaviorFactory", ContractName="Microsoft.Practices.Prism.Regions.IRegionBehaviorFactory")' on part 'Microsoft.Practices.Prism.MefExtensions.Regions.MefTabControlRegionAdapter'.

10) Change in exports prevented by non-recomposable import 'Microsoft.Practices.Prism.MefExtensions.Regions.MefSelectorRegionAdapter..ctor (Parameter="regionBehaviorFactory", ContractName="Microsoft.Practices.Prism.Regions.IRegionBehaviorFactory")' on part 'Microsoft.Practices.Prism.MefExtensions.Regions.MefSelectorRegionAdapter'.

11) Change in exports prevented by non-recomposable import 'Microsoft.Practices.Prism.MefExtensions.Regions.MefItemsControlRegionAdapter..ctor (Parameter="regionBehaviorFactory", ContractName="Microsoft.Practices.Prism.Regions.IRegionBehaviorFactory")' on part 'Microsoft.Practices.Prism.MefExtensions.Regions.MefItemsControlRegionAdapter'.

12) Change in exports prevented by non-recomposable import 'Microsoft.Practices.Prism.MefExtensions.Regions.MefContentControlRegionAdapter..ctor (Parameter="regionBehaviorFactory", ContractName="Microsoft.Practices.Prism.Regions.IRegionBehaviorFactory")' on part 'Microsoft.Practices.Prism.MefExtensions.Regions.MefContentControlRegionAdapter'.

13) More than one export was found that matches the constraint '((exportDefinition.ContractName == "Microsoft.Practices.Prism.Regions.IRegionViewRegistry") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "Microsoft.Practices.Prism.Regions.IRegionViewRegistry".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))'.

Resulting in: Cannot set import 'Microsoft.Practices.Prism.MefExtensions.Regions.Behaviors.MefAutoPopulateRegionBehavior..ctor (Parameter="regionViewRegistry", ContractName="Microsoft.Practices.Prism.Regions.IRegionViewRegistry")' on part 'Microsoft.Practices.Prism.MefExtensions.Regions.Behaviors.MefAutoPopulateRegionBehavior'.
Element: Microsoft.Practices.Prism.MefExtensions.Regions.Behaviors.MefAutoPopulateRegionBehavior..ctor (Parameter="regionViewRegistry", ContractName="Microsoft.Practices.Prism.Regions.IRegionViewRegistry") -->  Microsoft.Practices.Prism.MefExtensions.Regions.Behaviors.MefAutoPopulateRegionBehavior -->  AssemblyCatalog (Assembly="Microsoft.Practices.Prism.MefExtensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")

14) Change in exports prevented by non-recomposable import 'Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleManager.MefXapModuleTypeLoader (ContractName="Microsoft.Practices.Prism.MefExtensions.Modularity.MefXapModuleTypeLoader")' on part 'Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleManager'.

15) Change in exports prevented by non-recomposable import 'Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleManager..ctor (Parameter="moduleInitializer", ContractName="Microsoft.Practices.Prism.Modularity.IModuleInitializer")' on part 'Microsoft.Practices.Prism.MefExtensions.Modularity.MefModuleManager'.

    Check the InnerException property of the exception for more information. If the exception occurred
    while creating an object in a DI container, you can exception.GetRootException() to help locate the
    root cause of the problem.

I think the reason for this is that the module being downloaded also references teh PRISM dll's and it is trying to recompose them. How do I work around this?

Nov 15, 2010 at 5:06 AM

Hi,

I actually fixed the above issue a minute after posting this. I just set the CopyLocal to False for the PRISM dll's in my LocalModule1 project. But now I ran into another issue. When it tries to load the module it gives me this error

Unable to locate the module with type 'LocalModule1.Module, LocalModule1, Version=1.0.0.0' among the exported modules. Make sure the module name in the module catalog matches that specified on ModuleExportAttribute for the module type.

Not sure why. the ModuleExport attribute on the LocalModule1.Module does specify typeof(Module) but still I get this error.

Nov 15, 2010 at 6:44 AM
Edited Nov 15, 2010 at 10:28 AM

Hi,

Sorry for the trouble. I fixed the above by providing the contract name in the export.

I ran into the navigation framework in prism. It works well when calling RequestNavigate on a view within the same project. But when I try to call it on a view in another project it fails. I have the view decorated with the Export attribute and the Contract name same as the View name. But it doesnt seem to work

// Works : TestView is in same project

var regionManager = Container.GetExportedValue<IRegionManager>();
            var query = new UriQuery();
            query.Add("text", "Some query");
                      regionManager.RequestNavigate("Region1", new Uri("TestView" + query, UriKind.Relative));

// Doesnt work :  LocalModule1MainPage is a view in another silverlight application

var regionManager = Container.GetExportedValue<IRegionManager>();
            var query = new UriQuery();
            query.Add("text", "Some query");
            regionManager.RequestNavigate("Region2", new Uri("LocalModule1MainPage" + query, UriKind.Relative), NavigationCompleted);

Is it also possible to dowload an external xap into a region using RequestNavigate? By external I mean hosted under a different virtual directory altogether.

 

Nov 15, 2010 at 12:50 PM

Hi,

Do I need to post this in a separate discussion to get a response?