2017-06-11 1 views
0

Je suis en train de créer un programme d'amorçage LightInject pour Prism, j'ai copié le code du NinjectBootstrapper (source) et remplacé IKernel de Ninject avec LightInject de IServiceContainer. J'ai également créé et enregistré un LightInjectServiceLocatorAdapter (Ninject version).Création d'un LightInject Bootstrapper pour Prism, manquant enregistrement des adaptateurs région

L'adaptateur de localisation d'enregistrement et de service fonctionne. Je vois que la classe RegionAdapterMappings est récupérée avec succès à partir du localisateur de service.

Dans l'étape ConfigureRegionAdapterMappings du programme d'amorçage, une instance de la classe SelectorRegionAdapter est demandée au localisateur de service. Cela échoue. La classe n'a jamais été enregistrée. Je ne trouve aucune référence dans le NinjectBootstrapper. Alors, comment cette classe est-elle récupérée par le bootstrappeur Ninject?

J'ai essayé l'enregistrement de la classe manuellement (et quelques autres adaptateurs région et le DelayedRegionCreationBehavior) mais échoue Prism avec un UpdateRegionsException

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> Prism.Regions.Behaviors.RegionCreationException: An exception occurred while creating a region with name 'Menu'. The exception was: System.Collections.Generic.KeyNotFoundException: The IRegionAdapter for the type System.Windows.Controls.ContentControl is not registered in the region adapter mappings. You can register an IRegionAdapter for this control by overriding the ConfigureRegionAdapterMappings method in the bootstrapper. 

Je ne peux pas trouver une source traitant de la création d'ajouter votre propre DI conteneur et je n'ai aucune idée de ce que je suis manquant. Qu'est-ce que je fais mal?

Je configure mon ServiceContainer comme ceci (l'équivalent Ninject est la méthode ConfigureKernel).

protected virtual void ConfigureServiceContainer() 
{ 
    this.ServiceContainer.RegisterInstance<IServiceContainer>(this.ServiceContainer); 
    this.ServiceContainer.RegisterInstance(this.Logger); 
    this.ServiceContainer.RegisterInstance(this.ModuleCatalog); 

    if (!this.useDefaultConfiguration) 
     return; 

    this.ServiceContainer.Register<IServiceLocator, LightInjectServiceLocatorAdapter>(); 
    this.ServiceContainer.Register<IModuleInitializer, ModuleInitializer>(); 
    this.ServiceContainer.Register<IModuleManager, ModuleManager>(); 

    this.ServiceContainer.Register<RegionAdapterMappings, RegionAdapterMappings>(); 

    // The following 4 registrations are not in the NinjectBootstrapper 
    this.ServiceContainer.Register<SelectorRegionAdapter, SelectorRegionAdapter>(); 
    this.ServiceContainer.Register<ItemsControlRegionAdapter, ItemsControlRegionAdapter>(); 
    this.ServiceContainer.Register<ContentControlRegionAdapter, ContentControlRegionAdapter>(); 
    this.ServiceContainer.Register<DelayedRegionCreationBehavior, DelayedRegionCreationBehavior>(); 

    this.ServiceContainer.Register<IRegionManager, RegionManager>(); 
    this.ServiceContainer.Register<IEventAggregator, EventAggregator>(); 
    this.ServiceContainer.Register<IRegionViewRegistry, RegionViewRegistry>(); 
    this.ServiceContainer.Register<IRegionBehaviorFactory, RegionBehaviorFactory>(); 
    this.ServiceContainer.Register<IRegionNavigationJournalEntry, RegionNavigationJournalEntry>(); 
    this.ServiceContainer.Register<IRegionNavigationJournal, RegionNavigationJournal>(); 
    this.ServiceContainer.Register<IRegionNavigationService, RegionNavigationService>(); 
    this.ServiceContainer.Register<IRegionNavigationContentLoader, RegionNavigationContentLoader>(); 
} 
+0

Je vois deux votes serrés, mais je ne comprends pas pourquoi? Des commentaires à ce sujet? –

Répondre

0

Il s'avère qu'il y avait deux choses que j'ai fait mal. Pour l'enregistrement dans ConfigureServiceContainer, le bootstrappeur Ninject utilise une méthode d'extension public static void RegisterTypeIfMissing<A, B>(this IServiceContainer container, bool singletonScope) qui enregistre certaines des dépendances dans la portée singleton.

L'autre chose que je n'ai pas comprise est que Ninject résoudra heureusement n'importe quel type concret même s'il n'est pas enregistré. LightInject ne le fait pas. J'ai finalement résolu ce problème en enregistrant toutes les classes concrètes de Prism.WPF qui se terminent par « comportement » ou « adaptateur » se présente comme suit:

// Register all concrete adapters and behaviors in the Prism.WPF assembly 
var wpfAssembly = typeof (SelectorRegionAdapter).Assembly; 
this.ServiceContainer.RegisterAssembly(wpfAssembly, (t0, t1) => t0.Name.EndsWith("Adapter") || t0.Name.EndsWith("Behavior")); 

Enfin je devais abandonner toute la gestion du module de prisme. LightInject s'attend à ce qu'une seule classe qui s'étend de ICompositionRoot soit présente dans un assembly et chargera les types heureusement à partir de là. Cela fonctionne très bien pour mon approche :).