2012-05-02 2 views
1

Je souhaite lancer mon propre ViewModelLocator pour fournir un wrapper try/catch/log pour la création de ViewModel à un emplacement central de l'application, pour pouvoir le faire. Je dois remplacer le MvxDefaultViewModelLocator par défaut. Mais je n'ai pas trouvé un moyen de remplacer le générique, seulement pour injecter un type spécifique VM.Comment remplacer MvxDefaultViewModelLocator dans l'application MVVMCross

Comment injecter ma propre classe ViewModelLocator par défaut?

Répondre

0

Ceci est simple à faire ... mais pas réellement dans l'un des échantillons!

Le "conteneur" pour ViewModelLocators est l'objet MvxApplication. Par défaut, il utilise une convention basée sur MvxDefaultViewModelLocator qui essaie simplement de construire des instances ViewModel en utilisant leurs constructeurs déclarés qui ont des paramètres de chaîne.

Si vous souhaitez utiliser votre propre localisateur ViewModel, alors la voie est simple plus facile d'hériter de MvxViewModelLocator et de fournir soit des propriétés publiques ou les méthodes publiques qui renvoient vos instances ViewModel:

par exemple:

public class MyViewModelLocator : MvxViewModelLocator 
{ 
    public MyFirstViewModel CreateFirst() 
    { 
     return new MyFirstViewModel(); 
    } 

    public MySecondViewModel CreateSecond(string aParameter) 
    { 
     var someLookup1 = ComplicatedStaticThing1.Lookup(aParameter); 
     var viewModel = new MySecondViewModel(someLookup1); 

     var someLookup2 = ComplicatedStaticThing2.Lookup(aParameter, someLookup1); 
     viewModel.DoSomething(someLookup2); 

     return viewModel; 
    } 

    private readonly MyThirdViewModel _third = new MyThirdViewModel(); 
    public MyThirdViewModel Third 
    { 
     get 
     { 
      return _third; 
     } 
    } 
} 

Si vous voulez aller encore plus bas, vous pouvez également implémenter IMvxViewModelLocator directement à la place.

Pour ajouter le ViewModelLocator à l'application, il suffit d'instancier et l'ajouter dans votre application - par exemple:

public class App 
    : MvxApplication 
    , IMvxServiceProducer<IMvxStartNavigation> 
{ 
    public App() 
    { 
     this.RegisterServiceInstance<IMvxStartNavigation>(new StartApplicationObject()); 

     base.AddLocator(new MyViewModelLocator()); 

     // to disable the default ViewModelLocator, use: 
     // base.UseDefaultViewModelLocator = false; 
    } 
} 

Note: - sauf pour les données de temps de conception, je maintenant très rarement trouver le besoin de mettre en œuvre ViewModelLocator personnalisé - en général, tout ce que je veux faire peut être fait dans la construction ViewModel.

0

Je viens de relire votre question .... et j'ai répondu à une question différente, n'est-ce pas? Pardon!

Essayons encore ...


Le MvxApplication par défaut ne fournit aucun moyen de passer outre à ce membre. Si vous pensez que cela serait utile, alors posez un problème ou essayez GitHub.

Cependant, sans changer le code MVX, alors une façon d'obtenir l'effet que je pense que vous cherchez est de remplacer simplement l'interface IMvxViewModelLocatorFinder dans le cadre IoC/ServiceProvider - vous pouvez facilement mettre en œuvre:

public class MyFinder : IMvxViewModelLocatorFinder 
    { 
     public IMvxViewModelLocator FindLocator(MvxShowViewModelRequest request) 
     { 

      return new MyDefaultViewModelLocator(); 
     } 
    } 

et vous pouvez ensuite injecter cela (en remplaçant l'entrée Application dans IoC) au cours de la partie InitializeLastChance du programme d'installation pour chacun des projets client?


Sinon, vous pouvez aller encore plus haut si vous vouliez - vous pouvez remplacer la place IMvxViewModelLoader