How do I load modules dynamically in Prism / Composite Application Library?

I have a class in Prism / CAL application that generates a form for users to fill in data.

The form is defined by the XML file as follows:

<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>

      

the form should load specific elements that correspond to each type of field in XML like

  • Title (shows a dropdown menu: Mr., Ms., Dr., etc.).
  • Text (plain text box)
  • Email (text box with email verification)
  • ZipCode ( zipcode checked text box)

I want to make each control a separate module that is loaded so that, for example, the ZipCode module will exist in the Modules directory as a file:

ZipCode.dll

      

which is just a simple textbox that validates based on zipcode, but developers can make another control:

ZipCodePlus.dll

      

which inherits the same interface but provides a pop-up geo-earth selector for zip codes. As soon as the client replaces ZipCode.dll with ZipCodePlus.dll , all his forms will have this new functionality . > to search for zip codes.

However, I am having trouble rendering how this would be technically implemented, since since my form class parses XML it creates classes that provide functionality for the controls, but in order to instantiate the class I need to have a reference :

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

      

But how can I create an instance dynamically i.e. with the class name as a stringand if that class doesn't exist, it will throw a corresponding exception , for example something like this:

pseudocode:

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

      

+2


source to share


1 answer


You seem to be very close to a technical solution to your problem. I would just create an interface - IZipCodePresenter

- and in my module launch ZipCode.dll or ZipCodePlus.dll register the implementation.

Container.RegisterType<IZipCodePresenter, StandardZipCodePresenter>();

      

Then, in your parser, resolve the instance, for example:

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

      

Assuming no instances are registered for the interface, an exception will be thrown. Otherwise, you will get the last registered concrete IZipCodePresenter implementation. Note that an exception will only be thrown when trying to register an interface. If you try to register a class with Unity, it will instantiate based on Lifetime Manager policy.

If you want to continue working with this, you can create an interface ... something like IDynamicPresenter. Then you can register based on a known string (defined in your infrastructure project).



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

      

and then follow these steps:

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

      

I prefer the old solution, but this is definitely a valid option.

Hope this helps!

Ps This sounds like an interesting idea ... I would be interested to hear how you handle the implementation. You can even go a step further and build an entire XAML builder framework based on some of the concepts in ASP.NET MVC. This can make testing easier, but has the power of WPF. Good luck!

+3


source







All Articles