11
votes

Comment contrôler l'ordre de l'initialisation du module dans prisme

J'utilise Prism V2 avec un répertoireModulecatalog et j'ai besoin que les modules soient initialisés dans un certain ordre. L'ordre souhaité est spécifié avec un attribut sur chaque implémentation de l'immodile.

Ceci est de sorte que, comme chaque module soit initialisé, ils ajoutent leur vision dans une région TABControl et l'ordre des onglets doit être déterministe et contrôlé par l'auteur du module.

L'ordre n'implique pas une dépendance, mais plutôt un ordre qu'ils devraient être initialisés. En d'autres termes: les modules A, B et C peuvent avoir des priorités de 1, 2 et 3 respectivement. B n'a pas de dépendance sur A - il doit simplement être chargé dans la région Tabcontrol après A. afin que nous ayons une commande déterministe et contrôlable des onglets. Aussi, B pourrait ne pas exister au moment de l'exécution; Donc, ils chargeraient en tant que, c parce que la priorité devrait déterminer la commande (1, 3). Si j'avais utilisé la modulédecendabilité, le module "C" ne sera pas en mesure de charger avec toutes les dépendances de ce type.

Je peux gérer la logique de la manière de trier les modules, mais je ne peux pas comprendre à mettre ladite logique.


0 commentaires

7 Réponses :


0
votes

Dans l'appel de AddModule () Appelez dans la Bootstrapper, vous pouvez spécifier une dépendance. Donc, vous pouvez dire que cela dépend de B dépend de C, et qui déterminera la commande de charge.

http://msdn.microsoft.com/en-us/magazine /cc785479.aspx


1 commentaires

Je n'appelle pas "addmodule ()"; J'utilise le répertoireModulecatalog qui trouve toutes les imodules dans un chemin donné.



3
votes

Vous pouvez utiliser l'attribut code> moduleDePendance CODE> de votre classe de module pour indiquer au chargeur que votre module dépend des autres modules:

[ModuleDependency("SomeModule")]
[ModuleDependency("SomeOtherModule")]
public class MyModule : IModule
{
}


3 commentaires

Les modules ne sont pas des dépendances; Plus de détails ajoutés à la question


La dépendance n'est pas physique dans le sens où MyModule utilise quelque chose du somémodule et de quelque thermodile, mais il est plutôt logique que le chargement de MyModule dépend de ces deux autres modules chargés. Prisme ne se soucie pas du type de dépendances entre les modules et l'attribut ModulleDePendance peut être utilisé pour appliquer tout type de dépendance.


Dans mon exemple de A, B, C que j'ai récemment ajouté - B pourrait n'exister peut-être pas; Donc, ils chargeraient comme un, c parce que l'ordre est toujours correct (1, 3). Si j'ai utilisé la modulédecendabilité, le module "C" ne sera pas en mesure de charger avec toutes les dépendances de ce type.



2
votes

Vous pouvez remplacer la valeur par défaut imoduleinitializer em> pour une instance d'une classe personnalisée qui au lieu d'initialiser les modules juste après leur charge, les stocke dans une liste de modules. Lorsque tous les modules ont été chargés, vous les initialisez dans l'un quelconque ordre souhaité.

Comment réaliser ceci: p>

1) dans le bootstrapper, remplace la méthode Configurecontainer em> pour remplacer Par défaut imoduleinitializer em> pour une instance de la classe myModuleInitializer em>, maintenant l'initialiseur par défaut avec un nom (par exemple, faulfaulfaulOduleInitializer em>): P >

public class MyModuleInitializer : IModuleInitializer
{
    bool initialModuleLoadCompleted = false;
    IModuleInitializer defaultInitializer = null;
    List<ModuleInfo> modules = new List<ModuleInfo>();

    public MyModuleInitializer(IUnityContainer container)
    {
        defaultInitializer = container.Resolve<IModuleInitializer>("defaultModuleInitializer");
    }

    public void Initialize(ModuleInfo moduleInfo)
    {
        if(initialModuleLoadCompleted) {
            //Module loaded on demand after application startup - use the default initializer
            defaultInitializer.Initialize(moduleInfo);
            return;
        }

        modules.Add(moduleInfo);

        if(AllModulesLoaded()) {
            SortModules();
            foreach(var module in modules) {
                defaultInitializer.Initialize(module);
            }
            modules = null;
            initialModuleLoadCompleted = true;
        }
    }

    private bool AllModulesLoaded()
    {
        //Here you check whether all the startup modules have been loaded
        //(perhaps by looking at the module catalog) and return true if so
    }

    private void SortModules()
    {
        //Here you sort the "modules" list however you want
    }
}


2 commentaires

C'est une assez bonne solution. La seule partie délicate consiste à savoir quand "AllmodulesLaréd". Depuis que j'utilise le répertoireModulecatalog, je n'ai pas vraiment de moyen facile de savoir que. Merci d'avoir répondu; J'ai résolu le problème une manière complètement différente.


+1 J'aime celui-ci de plus que la réponse acceptée: Là je n'aime pas l'idée que les modules doivent savoir sur l'ordre dans lequel ils sont chargés, sans parler des noms de ces modules.



1
votes

J'ai résolu ceci en utilisant l'attribut modulédépendance et cela a fonctionné comme un charme


0 commentaires

15
votes

Je n'ai pas aimé l'idée d'utiliser Modulédecendabilité car cela signifierait que le module A ne se chargeait pas lorsque le module B n'était pas présent, en réalité, il n'y avait aucune dépendance. Au lieu de cela, j'ai créé un attribut prioritaire pour décorer le module: xxx

i puis décoré les modules comme celui-ci: xxx

J'ai créé un nouveau décendant de répertoireModulecatalog: xxx

Enfin, j'ai changé la bootstrapper pour utiliser ce nouveau catalogue: xxx

Je ne suis pas sûr que je ne suis pas sûr Si le truc avec le chargement de l'assemblage est le meilleur moyen de faire des choses, mais il semble fonctionner ...


2 commentaires

+1 J'ai voulu savoir comment faire cela depuis un certain temps. Merci beaucoup.


Excellente solution, exactement ce que je cherchais!



0
votes

Ramener le dos des morts car il semblerait avoir trouvé une solution différente que certaines pourraient trouver utiles. Je l'ai essayé et ça marche, mais je n'ai pas encore de ressentir tous les avantages et les inconvénients.

J'utilisais DistoireModulecatalog pour obtenir une liste de tous mes modules qui étaient tous placés dans un seul dossier. Mais j'ai remarqué que, pour la plupart, tous mes modules de "vue" dépendent de mes modules "Service", et c'était un modèle assez courant. Aucun service ne devrait dépendre d'une vue. Donc, cela m'a fait penser, que se passe-t-il si nous venons de mettre tous les modules de service dans un dossier et tous les modules de vue dans un autre et créé deux catalogues différents dans le bon ordre. Certains creusent et j'ai trouvé ce Article a > Cela mentionne quelque chose appelé AgregateMoDulecatalog, et il est utilisé pour concaténer ensemble un tas de catalogues. J'ai trouvé le code source de cette classe ici . Et voici comment je l'ai utilisé: p>

public class AggregateModuleCatalog : IModuleCatalog
{
    private List<IModuleCatalog> catalogs = new List<IModuleCatalog>();

    /// <summary>
    /// Initializes a new instance of the <see cref="AggregateModuleCatalog"/> class.
    /// </summary>
    public AggregateModuleCatalog()
    {
        this.catalogs.Add(new ModuleCatalog());
    }

    /// <summary>
    /// Gets the collection of catalogs.
    /// </summary>
    /// <value>A read-only collection of catalogs.</value>
    public ReadOnlyCollection<IModuleCatalog> Catalogs
    {
        get
        {
            return this.catalogs.AsReadOnly();
        }
    }

    /// <summary>
    /// Adds the catalog to the list of catalogs
    /// </summary>
    /// <param name="catalog">The catalog to add.</param>
    public void AddCatalog(IModuleCatalog catalog)
    {
        if (catalog == null)
        {
            throw new ArgumentNullException("catalog");
        }

        this.catalogs.Add(catalog);
    }

    /// <summary>
    /// Gets all the <see cref="ModuleInfo"/> classes that are in the <see cref="ModuleCatalog"/>.
    /// </summary>
    /// <value></value>
    public IEnumerable<ModuleInfo> Modules
    {
        get
        {
            return this.Catalogs.SelectMany(x => x.Modules);
        }
    }

    /// <summary>
    /// Return the list of <see cref="ModuleInfo"/>s that <paramref name="moduleInfo"/> depends on.
    /// </summary>
    /// <param name="moduleInfo">The <see cref="ModuleInfo"/> to get the</param>
    /// <returns>
    /// An enumeration of <see cref="ModuleInfo"/> that <paramref name="moduleInfo"/> depends on.
    /// </returns>
    public IEnumerable<ModuleInfo> GetDependentModules(ModuleInfo moduleInfo)
    {
        var catalog = this.catalogs.Single(x => x.Modules.Contains(moduleInfo));
        return catalog.GetDependentModules(moduleInfo);
    }

    /// <summary>
    /// Returns the collection of <see cref="ModuleInfo"/>s that contain both the <see cref="ModuleInfo"/>s in
    /// <paramref name="modules"/>, but also all the modules they depend on.
    /// </summary>
    /// <param name="modules">The modules to get the dependencies for.</param>
    /// <returns>
    /// A collection of <see cref="ModuleInfo"/> that contains both all <see cref="ModuleInfo"/>s in <paramref name="modules"/>
    /// and also all the <see cref="ModuleInfo"/> they depend on.
    /// </returns>
    public IEnumerable<ModuleInfo> CompleteListWithDependencies(IEnumerable<ModuleInfo> modules)
    {
        var modulesGroupedByCatalog = modules.GroupBy<ModuleInfo, IModuleCatalog>(module => this.catalogs.Single(catalog => catalog.Modules.Contains(module)));
        return modulesGroupedByCatalog.SelectMany(x => x.Key.CompleteListWithDependencies(x));
    }

    /// <summary>
    /// Initializes the catalog, which may load and validate the modules.
    /// </summary>
    public void Initialize()
    {
        foreach (var catalog in this.Catalogs)
        {
            catalog.Initialize();
        }
    }

    /// <summary>
    /// Adds a <see cref="ModuleInfo"/> to the <see cref="ModuleCatalog"/>.
    /// </summary>
    /// <param name="moduleInfo">The <see cref="ModuleInfo"/> to add.</param>
    public void AddModule(ModuleInfo moduleInfo)
    {
        this.catalogs[0].AddModule(moduleInfo);
    }
}


0 commentaires

0
votes

eu un problème similaire à une combinaison de Bowns Fergus de Bowns avec le SmartDirectoryCatalog proposé par Haukinger: multiples répertoireModulecatalog dans une application prisme . J'utilise cela pour "dépendances facultatives". J'espère que cela aidera quelqu'un.

PS: avec l'unité de prisme réelle 7.2 Vous devez remplacer ModuleInfo avec Imoduleinfo


0 commentaires