How to control the order of module initialization in Prism

后端 未结 7 831
暖寄归人
暖寄归人 2020-12-28 21:34

I\'m using Prism V2 with a DirectoryModuleCatalog and I need the modules to be initialized in a certain order. The desired order is specified with an attribute on each IModu

7条回答
  •  礼貌的吻别
    2020-12-28 22:17

    Bringing this back from the dead as I seem to have found a different solution that some might find useful. I tried it out and it works but I have yet to feel out all the pros and cons.

    I was using DirectoryModuleCatalog to get a list of all my modules which were all placed into a single folder. But I noticed that for the most part all my "View" modules depended on my "Service" modules, and that was a pretty common pattern. No service should depend on a view. So that got me thinking, what if we just put all the service modules into a folder and all the view modules into another and created two different catalogs in the correct order. Some digging around and I found this article that mentions something called an AggregateModuleCatalog, and it's used to concatenate together a bunch of catalogs. I found the source code for this class here. And here's how I used it:

    class Bootstrapper : UnityBootstrapper
    {
        protected override System.Windows.DependencyObject CreateShell() {...}
        protected override void InitializeShell() {...}
    
        protected override IModuleCatalog CreateModuleCatalog()
        {
            return new AggregateModuleCatalog();
        }
    
        protected override void ConfigureModuleCatalog()
        {
            ((AggregateModuleCatalog)ModuleCatalog).AddCatalog(new DirectoryModuleCatalog { ModulePath = "Modules.Services" });
            ((AggregateModuleCatalog)ModuleCatalog).AddCatalog(new DirectoryModuleCatalog { ModulePath = "Modules.Views" });
        }
    }
    

    And the AggregateModuleCatalog:

    public class AggregateModuleCatalog : IModuleCatalog
    {
        private List catalogs = new List();
    
        /// 
        /// Initializes a new instance of the  class.
        /// 
        public AggregateModuleCatalog()
        {
            this.catalogs.Add(new ModuleCatalog());
        }
    
        /// 
        /// Gets the collection of catalogs.
        /// 
        /// A read-only collection of catalogs.
        public ReadOnlyCollection Catalogs
        {
            get
            {
                return this.catalogs.AsReadOnly();
            }
        }
    
        /// 
        /// Adds the catalog to the list of catalogs
        /// 
        /// The catalog to add.
        public void AddCatalog(IModuleCatalog catalog)
        {
            if (catalog == null)
            {
                throw new ArgumentNullException("catalog");
            }
    
            this.catalogs.Add(catalog);
        }
    
        /// 
        /// Gets all the  classes that are in the .
        /// 
        /// 
        public IEnumerable Modules
        {
            get
            {
                return this.Catalogs.SelectMany(x => x.Modules);
            }
        }
    
        /// 
        /// Return the list of s that  depends on.
        /// 
        /// The  to get the
        /// 
        /// An enumeration of  that  depends on.
        /// 
        public IEnumerable GetDependentModules(ModuleInfo moduleInfo)
        {
            var catalog = this.catalogs.Single(x => x.Modules.Contains(moduleInfo));
            return catalog.GetDependentModules(moduleInfo);
        }
    
        /// 
        /// Returns the collection of s that contain both the s in
        /// , but also all the modules they depend on.
        /// 
        /// The modules to get the dependencies for.
        /// 
        /// A collection of  that contains both all s in 
        /// and also all the  they depend on.
        /// 
        public IEnumerable CompleteListWithDependencies(IEnumerable modules)
        {
            var modulesGroupedByCatalog = modules.GroupBy(module => this.catalogs.Single(catalog => catalog.Modules.Contains(module)));
            return modulesGroupedByCatalog.SelectMany(x => x.Key.CompleteListWithDependencies(x));
        }
    
        /// 
        /// Initializes the catalog, which may load and validate the modules.
        /// 
        public void Initialize()
        {
            foreach (var catalog in this.Catalogs)
            {
                catalog.Initialize();
            }
        }
    
        /// 
        /// Adds a  to the .
        /// 
        /// The  to add.
        public void AddModule(ModuleInfo moduleInfo)
        {
            this.catalogs[0].AddModule(moduleInfo);
        }
    }
    

    I should also mention that the article states the following:

    To demonstrate multiple ways of using the ModuleCatalog, the QuickStart using Unity implements an AggregateModuleCatalog that derives from IModuleCatalog. This class is not intended to be used in a shipping application.

    Why that is I'm not sure. Would love to hear any explanations as to why that might be.

提交回复
热议问题