2009-09-14 5 views
2

J'ai une classe dans mon application Prism/CAL qui génère un formulaire pour les utilisateurs à remplir des données.Comment charger dynamiquement des modules dans la bibliothèque d'applications Prism/Composite?

La forme est définie par un fichier XML comme ceci:

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

la forme doit charger spécifiques de contrôle qui correspondent à chaque type de champ dans le fichier XML, par exemple

  • Titre (montre un menu déroulant: Monsieur, Madame, Dr, etc.)
  • Texte (zone de texte simple,)
  • Email (textbox avec validation e-mail)
  • ZipCode (zone de texte avec la validation du code postal)

Je veux que chaque commande soit un module séparé qui soit chargé de telle sorte que par exemple. le module ZipCode existerait dans un répertoire des modules sous forme de fichier:

ZipCode.dll 

qui est juste une zone de texte simple, contrôle qui valide basé sur code postal, mais les développeurs pourrait faire un autre contrôle appelé:

ZipCodePlus.dll 

qui hérite du même interface mais fournit un sélecteur de géo-terre pop-up pour les codes postaux. Dès qu'un client a remplacé ZipCode.dll avec ZipCodePlus.dll, toutes ses formes aurait cette nouvelle fonctionnalité pour la recherche de codes postaux.

Cependant, je vais avoir du mal à visualiser la façon dont cela sera techniquement mis en œuvre, depuis que ma classe de formulaire est l'analyse du XML, il instancie les classes qui fournissent la fonctionnalité des contrôles, mais pour instancier la classe , je dois avoir une référence à elle:

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

Mais comment puis-je instancier dynamiquement, à savoir le nom de la classe comme une chaîne , et si cette classe n'existe pas, il va jeter un approp rité exception, par ex. quelque chose comme ceci:

PSEUDO-CODE:

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

Quelle sorte d'analyseur utilisez-vous? est-ce chargement paresseux ou chargement impatient. Nous utilisons également une approche similaire. – Mohanavel

Répondre

3

Il semble que vous êtes très proche d'une solution technique à votre problème.Je voudrais simplement créer une interface - IZipCodePresenter - et dans mon démarrage de module ZipCode.dll ou ZipCodePlus.dll, enregistrez l'implémentation.

Container.RegisterType<IZipCodePresenter, StandardZipCodePresenter>(); 

Ensuite, dans votre analyseur, résoudre l'instance comme:

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

En supposant aucun cas sont enregistrés pour l'interface, une exception sera levée. Sinon, vous obtiendrez la dernière implémentation concrète enregistrée de IZipCodePresenter. Notez qu'une exception ne sera levée que si vous essayez d'enregistrer une interface. Si vous tentez d'enregistrer une classe avec Unity, elle créera une instance basée sur la stratégie Lifetime Manager.

Si vous voulez aller plus loin, vous pouvez créer une interface ... quelque chose comme IDynamicPresenter. Vous pouvez ensuite vous inscrire en fonction d'une chaîne connue (définie dans votre projet d'infrastructure).

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

puis résoudre comme ce qui suit:

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

Je préfère la première solution, mais cela est certainement une option valable.

Espérons que cela aide!

P.s. Cela semble être une idée intéressante ... Je serais intéressé de savoir comment vous allez avec la mise en œuvre. Vous pouvez même aller plus loin et créer un framework de construction XAML complet basé sur certains des concepts de ASP.NET MVC. Il pourrait faciliter la mise à l'essai, tout en ayant la puissance de WPF. Bonne chance!

Questions connexes