Модуляризация приложения C # Compact Framework 2.0 - PullRequest
2 голосов
/ 06 января 2009

В настоящее время мы разрабатываем новую часть ручного программного обеспечения. Я не могу обсудить природу приложения, поэтому вместо этого я буду использовать пример.

Мы разрабатываем портативное программное обеспечение для управления школой. Мы хотим модулировать каждый аспект системы, чтобы разные школы могли использовать разные функции.

Наша система запустится с главным меню и экраном входа. Я хотел бы, чтобы это было основой системы и где модули будут добавлены. То есть У меня будет проект под названием SchoolPda.

Тогда я хочу иметь разные модули. Т.е. я хочу модуль регистрации, который будет обрабатывать регистрацию студентов. Я хочу учебный модуль для управления чистотой в классе и т. Д.

Способ, которым я мог бы видеть эту работу, включает / не включает в себя различные библиотеки DLL и наличие кнопок главного меню базовой системы для доступа к этим модулям, если библиотеки DLL существуют. Это то, что мы ищем.

У кого-нибудь есть опыт, чтобы сделать что-то подобное? Каков будет лучший способ сделать это? Нам не нужно беспокоиться о базе данных, поскольку база данных всегда будет полной базой данных, но аспекты не будут заполняться, если связанные модули не существуют.

Ответы [ 4 ]

3 голосов
/ 06 января 2009

В настоящее время я также занимаюсь разработкой приложения, которое работает как на компактной, так и на полной платформе и построено по модульному принципу.

Способ, который я реализовал, заключается в том, что он сканирует местоположение для DLL и перечисляет все типы и определяет, есть ли у них определенный "ScreenInfoAttribute" или "WidgetInfoAttribute", который содержит полезную информацию о классе.

вот фрагмент кода, он содержит код 3.5, но это потому, что мы недавно сделали переход с 2.0, но принцип работает в 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;
    }
3 голосов
/ 06 января 2009

Я был в проектах, которые делали это двумя способами:

  • В одном проекте мы не развернули определенные библиотеки DLL, если у клиентов не было лицензии. Это то, что вы предлагаете. Работало нормально. Конечно, невозможно было включить эти модули без дополнительной установки, но для этого приложения это имело смысл.

  • В другом проекте мы развернули все и предоставили конечным пользователям только меню, кнопки и т. Д., На которые у клиента была лицензия. Мы сделали это, потому что тогда пользователь мог легко добавить дополнительный модуль, добавив для него лицензию. Когда лицензия была добавлена, материал волшебным образом обнаружился при следующем входе в систему.

Итак, по моему опыту, я бы сказал, посмотрите на вашу модель лицензирования как на один большой кусок вашего решения. Подумайте, хотите ли вы когда-нибудь добавить эти дополнительные модули на лету.

0 голосов
/ 06 января 2009

Просто дайте каждому модулю реализовать общий интерфейс. Добавьте методы, такие как GetButtons () или GetActions ().

Затем вы можете поместить информацию о AssemblyName и ClassName в файл конфигурации. Теперь легко загрузить указанную сборку и создать экземпляр класса с помощью Activator.CreateInstance, привести его к интерфейсу и вызвать методы GetButtons () и т. Д.

0 голосов
/ 06 января 2009

Я не знаю, будет ли это работать на CLR, но взгляните на MEF , чтобы создать способ обнаружить и загрузить ваши dll / модули. У ваших модулей также может быть метод GetMenuItem (или что-то в этом роде), который получает требуемую информацию, чтобы ваше главное меню могло добавить кнопку.

Очевидно, используйте другой дизайн для вашего главного меню, если это имеет смысл, но вы хотите, чтобы оно действительно было модульным и расширяемым, чтобы вы могли писать свое ядро ​​и в будущем продолжать писать новые компоненты, без необходимости менять ядро.

Извините, если это не имеет большого смысла. Просто надеялся дать вам идею в одном направлении.

...