Question

Im essayant de se familiariser avec l'écriture ViewModels testables dans Silverlight 4. Im actuellement en utilisant la lumière MVVM.

Im en utilisant AutoFac et le IoCContainer fait son bien du travail. Cependant, pour injecter dans le constructeur de ViewModels, qui sont liés à ce que j'ai vues Enchaînement constructeur:

    public UserViewModel() : this(IoCContainer.Resolve<IUserServiceAsync>())
    {

    }

    public UserViewModel(IUserServiceAsync userService) 
    {
        if (this.IsInDesignMode) return;

        _userService = userService;
    }

Ce qui ne se sent pas propre, mais est la meilleure option que j'ai trouvé jusqu'à présent. Cela fonctionne et mes travaux d'applications selon vos besoins, est testable avec le contrôle inversée.

Cependant, avec ma VM lié à mon avis comme ceci:

 <UserControl.DataContext>
            <ViewModel:UserViewModel />
 </UserControl.DataContext>

Dans mes attributs de page XAML, le mode de conception à la fois ne fonctionne pas VS2010 et de ses mélanges.

Est il y a plus agréable moyen de parvenir à ce que im essayant de Silverlight qui fonctionne toujours avec le mode de conception? Perdre le mode de conception ne est pas un briseur d'affaire, mais sera à portée de main tout en apprenant XAML. Un rien plus propre chemin enchaîné serait bien si!

Im pensant qu'il peut possible d'utiliser AutoFac / IoC pour résoudre viewmodels à vue, par opposition à l'approche de balisage XAML ci-dessus, et descendre cette route?

Merci.

Était-ce utile?

La solution

Au lieu de mettre en œuvre le premier constructeur, je vous suggère de mettre en œuvre un ViewModelLocator, comme ceci:

public class ViewModelLocator
{

    IoCContainer Container { get; set; }

    public IUserViewModel UserViewModel
    {
        get
        {
            return IoCContainer.Resolve<IUserViewModel>();
        }
    }

}

Alors en XAML vous déclarez le localisateur comme une ressource statique:

<local:ViewModelLocator x:Key="ViewModelLocator"/>

Pendant que vous initialisez votre application, il est nécessaire de fournir le localisateur avec l'instance du conteneur:

var viewModelLocator = Application.Current.Resources["ViewModelLocator"] as ViewModelLocator;
if(viewModelLocator == null) { // throw exception here }
viewModelLocator.Container = IoCContainer;

Ensuite, en XAML vous pouvez utiliser la ressource proprement:

<UserControl
    DataContext="{Binding Path=UserViewModel, Source={StaticResource ViewModelLocator}}"
    />
    <!-- The other user control properties -->

Pour le temps de conception, vous pouvez mettre en œuvre un MockViewModelLocator:

public class MockViewModelLocator
{

    public IUserViewModel UserViewModel
    {
        get
        {
            return new MockUserViewModel();
        }
    }

}

Déclarez en XAML de façon appropriée:

<local:MockViewModelLocator x:Key="MockViewModelLocator"/>

Et enfin l'utiliser dans votre contrôle utilisateur:

<UserControl
    d:DataContext="{Binding Path=UserViewModel, Source={StaticResource MockViewModelLocator}}"
    DataContext="{Binding Path=UserViewModel, Source={StaticResource ViewModelLocator}}"
    />
    <!-- The other user control properties -->

Vous pouvez faire votre retour en toute sécurité de recherche de modèle de vue maquette et des données facilement lisibles pour un mélange à utiliser et lors de l'exécution, vous utiliserez votre service réel.

De cette façon, vous faire des données de temps de conception ne perd jamais et vous ne devez pas sacrifier la propreté de la méthode d'injection de dépendance dans vos modèles de vue.

J'espère que cette aide.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top