2010-08-15 10 views
0

Im travaillant avec le modèle MVVM + une implémentation ServiceLocator simple, maintenant à mon problème comment suis-je censé configurer les services lorsque les vues sont en cours d'exécution dans le temps de conception?Services de conception d'installation MVVM?

Iv essayé this mais il ne semble pas fonctionner dans VS 2010 ou quelque chose, je sais que cela a fonctionné sur mon ancien ordinateur, mais sur mon nouveau, il ne fonctionne pas. Est-ce que quelqu'un connaît une bonne alternative?

Edit: (Au nom de Merlyn Morgan-Graham)

bien ce que Im essayant de faire est, j'ai mon avis, ViewModel et services maintenant la différence ici est que j'ai 2 implémentations de chaque service un pour le temps de conception et un pour l'exécution. pour une meilleure explication, regardez here.

+0

Je sais (un peu) quel est le localisateur de service, je sais ce que «en conception» est, et je sais ce que MVVM est, mais je ne sais pas pourquoi vous Vous souhaitez vous connecter aux services au moment du design. Quel problème essayez-vous de résoudre ici? Un peu plus de contexte peut être utile pour quelqu'un qui essaie de trouver des alternatives pour vous. Et si la même configuration et le même code ont fonctionné pour vous sur votre autre ordinateur, cela ressemble à un problème de support technique plutôt qu'à un problème de programmation ..? –

+0

J'ai ajouté une modification pour que je puisse vous donner un meilleur aperçu! – Peter

+0

@Petoj: Où se décompose-t-il, la connexion view-> viewmodel, ou la connexion viewmodel-> dal/servicelocator? –

Répondre

1

Si vous voulez découpler votre point de vue de votre viewmodel et votre viewmodel de votre model/dal (en fait, si vous voulez utiliser MVVM), alors votre modèle de vue et votre modèle de données ne devraient rien savoir sur le temps de conception. Le temps de conception s'applique uniquement à la vue.

Cet article montre une manière de définir vos données de temps de conception via XML/XAML, de sorte que votre code ne sous pas savoir quoi que ce soit à son sujet:

http://karlshifflett.wordpress.com/2009/10/21/visual-studio-2010-beta2-sample-data-project-templates/

après modification: Il se que vous devrez toujours utiliser votre modèle de vue pour que vos liaisons XAML existantes fonctionnent. Cela va juste peupler le modèle de vue plutôt que d'avoir à créer un nouveau modèle de données. Je ne suis pas sûr, mais il pourrait y avoir des classes qui vous permettent d'utiliser le mécanisme de liaison WPF pour prendre soin de cela ... Vues?

CV Avant Modifier ...: En ce qui concerne la solution dans l'article que vous avez lié d'abord, le concepteur n'instancier rien, mais votre classe, et le code il fait référence. Cela signifie que les attributs d'assemblage ne seront pas instanciés à moins que votre code d'affichage ne les référence directement. Si vous voulez vraiment coupler vos modèles d'affichage à vos vues pendant la conception, et faire en sorte que les services de conception soient enregistrés, vous devez placer le code d'enregistrement du service dans votre classe de vue, ou une classe dans la vue. classe directement les références.

Pour ce faire, vous pouvez utiliser des constructeurs statiques de vos vues pour enregistrer vos services de conception. Vous pouvez également écrire une méthode statique sur une autre classe (application?) Pour enregistrer (conditionnellement) les services de conception. Ensuite, appelez cette méthode dans le constructeur de vos vues.

Ou vous pouvez simplement les enregistrer dans le constructeur pour chacune de vos vues.

Fondamentalement, ce que vous voulez faire est possible, mais cette méthode liée dans le premier article ne l'est pas. Si vous lisez plus loin dans les commentaires, vous verrez que sa méthode est cassée.

Vous pouvez également contester l'idée d'accrocher votre modèle de vue à votre vue pendant la conception, car le modèle MVVM a été créé pour éviter ce genre de chose.

0

Vous n'avez généralement pas besoin d'accéder aux services au moment de la conception ... En règle générale, vous n'utilisez même pas vos ViewModels réels au moment du design, vous utilisez des données de conception fictives, comme expliqué here. Si vous avez vraiment besoin d'utiliser vos ViewModels réels, vous pouvez implémenter des versions fictives de vos services, et de les utiliser au lieu des services réels:

if (DesignerProperties.GetIsInDesignMode(new DependencyObject())) 
{ 
    // Design time 
    ServiceLocator.Instance.Register<IService1>(new DummyService1()); 
    ServiceLocator.Instance.Register<IService2>(new DummyService2()); 
} 
else 
{ 
    // Run time 
    ServiceLocator.Instance.Register<IService1>(new RealService1()); 
    ServiceLocator.Instance.Register<IService2>(new RealService2()); 
} 
+0

bien oui mon but est d'utiliser des services factices mais où est-ce que je mets ce code qui enregistre les services afin qu'il fonctionne en temps de conception? – Peter

+0

Bonne question ... En général, je mets l'initialisation du service dans la méthode OnStartup de l'App, mais cette méthode n'est pas exécutée au moment du design. Êtes-vous sûr que cela ne fonctionne pas avec l'attribut DesignTimeBootstrapper mentionné dans l'article de Josh Smith? –

+0

Petoj: Je viens de l'essayer. ne fonctionne pas pour moi :( –

0

Je suis également d'accord avec tous ceux qui ont des préoccupations concernant l'utilisation du localisateur de service au moment de la conception, je crois que c'est un scénario valable dans certains cas d'utilisation. Ce n'est pas une discussion sur pourquoi/pourquoi pas, c'est simple comme ça (presque) a fonctionné pour moi. Il y a encore un problème que je n'ai pas encore résolu: cela ne fonctionne que pour une vue à la fois.

  1. Créez un bootstrappeur simple pour configurer votre IoC de votre choix. Notez l'interface ISupportInitialize.

    public class Bootstrapper: ISupportInitialize 
    { 
        #region ISupportInitialize Members 
    
        public void BeginInit() { } 
    
        public void EndInit() 
        { 
         if (DesignerProperties.GetIsInDesignMode(new DependencyObject())) 
          Setup(); 
        } 
    
        #endregion 
    
        public static void Setup() { SetupServiceLocator(); } 
    
        static void SetupServiceLocator() 
        { 
         ContainerBuilder builder = new ContainerBuilder(); 
         builder.RegisterType<ConfigService>().As<IConfigService>().ExternallyOwned().SingleInstance(); 
         IContainer container = builder.Build(); 
    
         ServiceLocator.SetLocatorProvider(() => new AutofacServiceLocator(container)); 
        } 
    } 
    
  2. Utilisez le Bootstrapper comme avant pour le mode d'exécution, par exemple:

    public partial class App : Application 
    { 
        protected override void OnStartup(StartupEventArgs e) 
        { 
         base.OnStartup(e); 
         Bootstrapper.Setup(); 
        } 
    } 
    
  3. De plus, vous devez l'ajouter aux ressources d'application pour le soutien du mode de conception:

    <Application x:Class="MonitoringConfigurator.App" 
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
          xmlns:local="clr-namespace:MyBootstrapperNamespace" 
          StartupUri="MainWindow.xaml"> 
        <Application.Resources> 
         <local:Bootstrapper x:Key="Bootstrapper" /> 
        </Application.Resources> 
    </Application>