Question

Nous développons actuellement un nouveau logiciel portatif. Je ne peux pas discuter de la nature de l'application, je vais donc utiliser un exemple à la place.

Nous concevons un logiciel de poche pour gérer une école. Nous voulons modulariser chaque aspect du système afin que différentes écoles puissent utiliser différentes fonctionnalités.

Notre système commencera par un menu principal et un écran de connexion. J'aimerais que ceci soit la base du système et soit l'endroit où les modules seront ajoutés. C'est à dire. Je vais avoir un projet appelé SchoolPda.

Je veux alors avoir différents modules. C'est-à-dire que je veux un module d'inscription qui gérera les inscriptions d'étudiants. Je veux un module de classe pour gérer la propreté de la classe, etc.

La façon dont cela fonctionnerait serait d'inclure ou non différentes dll et d'avoir le menu principal du système de base permettant d'afficher les boutons permettant d'accéder à ces modules si les dll existent. C'est exactement le genre de chose que nous recherchons.

Quelqu'un at-il déjà fait quelque chose comme ça? Quelle serait la meilleure façon de le faire? Nous n'avons pas à nous soucier de la base de données car celle-ci sera toujours la base de données complète, mais les aspects ne seront pas renseignés si les modules associés n'existent pas.

Était-ce utile?

La solution

J'ai participé à des projets qui l'ont fait de deux manières:

  • Dans un projet, nous n'avons pas déployé certaines DLL si les clients n'étaient pas sous licence. C'est ce que vous suggérez. Cela a bien fonctionné. Bien sûr, il n'y avait aucun moyen d'activer ces modules sans une installation supplémentaire, mais cela était parfaitement logique pour cette application.

  • Dans un autre projet, nous avons tout déployé et exposé uniquement aux utilisateurs finaux les menus, boutons, etc. pour lesquels le client avait une licence. Nous l'avons fait parce qu'alors l'utilisateur pouvait facilement ajouter un module supplémentaire en ajoutant une licence pour celui-ci. Lorsque la licence a été ajoutée, le contenu est apparu comme par magie lors de la prochaine connexion.

Donc, selon mon expérience, je dirais que votre modèle de licence constitue un élément important de votre décision. Demandez-vous si vous voudrez un jour ajouter ces modules supplémentaires à la volée.

Autres conseils

Je développe actuellement également une application fonctionnant à la fois sur les infrastructures Compact et Full et construite de manière modulaire.

Comme je l’ai implémenté, il analyse un emplacement à la recherche de dll, les énumère pour chaque type et examine s’ils ont un " ScreenInfoAttribute " ou " WidgetInfoAttribute " défini qui contient des informations utiles sur la classe.

voici un extrait, il contient du code 3.5, mais c'est parce que nous avons récemment basculé depuis la version 2.0, mais le principe fonctionne dans la version 2.0

public void Analyze(FileInfo file) {
        Assembly asm = Assembly.LoadFrom(file.FullName);
        List<Data.AnyPlugin> types = GetPluginTypes(asm.GetTypes());

        if (types.Count > 0) {
            types.ForEach(x => x.AssemblyPath = file.FullName);
            if (_plugins.ContainsKey(file.FullName)) {
                _plugins[file.FullName].Plugins.AddRange(types);
            } else {
                AssemblyPlugin asp = new AssemblyPlugin();
                asp.Ass = asm;
                asp.Plugins = types;
                _plugins.Add(file.FullName, asp);
            }
        }
    }

    private List<Data.AnyPlugin> GetPluginTypes(Type[] types) {
        List<Data.AnyPlugin> returnTypes = new List<AnyPlugin>();
        foreach (Type t in types) {
            Data.AnyPlugin st = GetPluginType(t);
            if (st != null) returnTypes.Add(st);
        }
        return returnTypes;
    }

    private Data.AnyPlugin GetPluginType(Type type) {
        if (type.IsSubclassOf(typeof(Screens.bScreen<T>))) {
            Screens.ScreenInfoAttribute s = GetScreenAttrib(type);
            if (s != null) {
                return new Data.ScreenPlugin("", type, s);
            }
        } else if (type.IsSubclassOf(typeof(Widgets.bWidget<T>))) {
            Widgets.WidgetInfoAttribute w = GetWidgetAttrib(type);
            if (w != null) return new Data.WidgetPlugin("", type, w);
        }
        return null;
    }

    private Screens.ScreenInfoAttribute GetScreenAttrib(Type t) {
        Attribute a = Attribute.GetCustomAttribute(t, typeof(Screens.ScreenInfoAttribute));
        return (Screens.ScreenInfoAttribute)a;
    }

Je ne sais pas si cela fonctionnera sur le CLR mais jetez un coup d'œil à MEF . , pour créer un moyen de découvrir et de charger vos dlls / modules. Vous pouvez également demander à vos modules d’avoir une méthode GetMenuItem (ou quelque chose de similaire) qui obtienne les informations requises pour que votre menu principal puisse ajouter un bouton.

Évidemment, utilisez un modèle différent pour votre menu principal si cela vous semble judicieux, mais vous souhaiterez qu'il soit réellement modulable et extensible, de sorte que vous puissiez écrire votre coeur et continuer à écrire de nouveaux composants, sans avoir à vous changer de base.

Je suis désolé si cela n’a pas beaucoup de sens. J'espère juste vous donner une idée dans une direction.

Laissez chaque module implémenter une interface commune. Ajoutez des méthodes telles que GetButtons () ou GetActions ().

Vous pouvez ensuite placer les informations sur le nom d'assembly et le nom de classe dans un fichier de configuration. Maintenant, il est facile de charger l’assembly spécifié et de créer une instance de la classe avec Activator.CreateInstance, transtypez-la sur votre interface et appelez les méthodes GetButtons (), etc.

.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top