Как динамически загружать модули в Prism / Composite Application Library? - PullRequest
2 голосов
/ 14 сентября 2009

У меня есть класс в моем приложении Prism / CAL, которое создает форму для пользователей, чтобы заполнить данные.

Форма определяется файлом XML следующим образом:

<area idCode="general" title="General">
    <column>
        <group title="Customer Data">
            <field idCode="title" requiredStatus="true">
                <label>title</label>
                <fieldType>Title</fieldType>
            </field>
            <field idCode="firstName" requiredStatus="true">
                <label>First Name</label>
                <fieldType>Text</fieldType>
            </field>
            <field idCode="lastName" requiredStatus="true">
                <label>Last Name</label>
                <fieldType>Text</fieldType>
            </field>
            <field idCode="email" requiredStatus="true">
                <label>E-Mail</label>
                <fieldType>Email</fieldType>
            </field>
            ...
        </group>
        </column>
    </area>

форма должна загружать определенные элементы управления, которые соответствуют каждому типу поля в XML, например,

  • Заголовок (показывает раскрывающийся список: г-н, миссис, доктор и т. Д.)
  • Текст (простое текстовое поле)
  • Электронная почта (текстовое поле с подтверждением электронной почты)
  • ZipCode (текстовое поле с проверкой почтового индекса)

Я хочу сделать каждый элемент управления отдельным модулем, который загружается так, например, модуль ZipCode будет находиться в каталоге модулей в виде файла:

ZipCode.dll

, который представляет собой просто простое текстовое поле элемент управления, который проверяет на основе почтового индекса, но разработчики могут создать другой элемент управления под названием:

ZipCodePlus.dll

, который наследует тот же интерфейс , но предоставляет всплывающий селектор геоземли для почтовых индексов. Как только клиент заменит ZipCode.dll на ZipCodePlus.dll , все его формы будут иметь эту новую функциональность для поиска почтовые индексы.

Однако у меня возникают проблемы с визуализацией того, как это будет технически реализовано, так как мой класс формы анализирует XML, он создает экземпляры классов, которые предоставляют функциональные возможности для элементов управления, но для создания экземпляра класс, у меня должна быть ссылка на него:

SmartFormFieldZipCodePresenter smartFormFieldEmailPresenter
    = container.Resolve<SmartFormFieldEmailPresenter>();

Но как я могу создать его динамически , то есть с именем класса в виде string , и если этот класс не существует, он выдаст соответствующий исключение , например как то так:

псевдокод:

try {
    var smartFormFieldZipCodePresenter
        = container.Resolve("smartFormFieldZipCodePresenter");
}
catch (ModuleDoesNotExistException) {
    ...
}

1 Ответ

3 голосов
/ 14 сентября 2009

Кажется, вы очень близки к техническому решению вашей проблемы. Я просто создал бы интерфейс - IZipCodePresenter - и при запуске модуля ZipCode.dll или ZipCodePlus.dll зарегистрируйте реализацию.

Container.RegisterType<IZipCodePresenter, StandardZipCodePresenter>();

Затем в вашем парсере разрешите экземпляр следующим образом:

var zipCodePresenter = container.Resolve<IZipCodePresenter>();

Если для интерфейса не зарегистрированы экземпляры, будет выдано исключение. В противном случае вы получите последнюю зарегистрированную конкретную реализацию IZipCodePresenter. Обратите внимание, что исключение будет выдано только если вы попытаетесь зарегистрировать интерфейс. Если вы попытаетесь зарегистрировать класс в Unity, он создаст экземпляр на основе политики Lifetime Manager.

Если вы хотите пойти дальше с этим, вы можете создать интерфейс ... что-то вроде IDynamicPresenter. Затем вы можете зарегистрироваться на основе известной строки (определенной в вашем инфраструктурном проекте).

Container.RegisterType<IDynamicPresenter, StandardZipCodePresenter>(PresenterName.ZipCodeControl);
Container.RegisterType<IDynamicPresenter, StandardEmailPresenter>(PresenterName.EmailControl);

, а затем разрешите следующим образом:

var zipCodeControl = Container.Resolve<IDynamicPresenter>(PresenterName.ZipCodeControl);
var emailControl = Container.Resolve<IDynamicPresenter>(PresenterName.EmailControl);

Я предпочитаю первое решение, но это, безусловно, верный вариант.

Надеюсь, это поможет!

P.s. Это звучит как интересная идея ... Мне было бы интересно услышать, как вы продвигаетесь в реализации. Вы можете даже сделать еще один шаг вперед и создать целую платформу XAML-компоновщика, основанную на некоторых концепциях ASP.NET MVC. Это может облегчить тестирование, но при этом иметь силу WPF. Удачи!

...