Как динамически загружать модули в библиотеку приложений Prism/Composite?

StackOverflow https://stackoverflow.com/questions/1420539

Вопрос

у меня есть сорт в моем приложении 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.dll

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

ZipCodePlus.dll

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

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

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

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

ПСЕВДО-КОД:

try {
    var smartFormFieldZipCodePresenter
        = container.Resolve("smartFormFieldZipCodePresenter");
}
catch (ModuleDoesNotExistException) {
    ...
}
Это было полезно?

Решение

Кажется, вы очень близки к техническому решению вашей проблемы.Я бы просто создал интерфейс - 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.Удачи!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top