Silverlight Constructor injection into View Model + Design Mode
Próbuję uporać się z pisaniem testowalnych modeli w Silverlight 4. Im obecnie używa światła MVVM.
Używam AutoFac i IoCContainer wykonuje swoją pracę dobrze. Jednak aby wprowadzić do konstruktora ViewModels, które są powiązane z widokami mam ten konstruktor chaining:
public UserViewModel() : this(IoCContainer.Resolve<IUserServiceAsync>())
{
}
public UserViewModel(IUserServiceAsync userService)
{
if (this.IsInDesignMode) return;
_userService = userService;
}
Która nie wydaje się czysta, ale jest najlepszą opcją, jaką do tej pory znalazłem. To działa, a moja aplikacja działa zgodnie z życzeniem i można ją przetestować z odwróconą kontrolą.
Jednak z moim VM związane z moim zdaniem tak:
<UserControl.DataContext>
<ViewModel:UserViewModel />
</UserControl.DataContext>
W moich atrybutach strony XAML, Tryb projektowania zarówno w VS2010, jak i Blend nie działa.
Czy istnieje ładniejszy sposób, aby osiągnąć to, co próbuję w Silverlight, który nadal działa z trybem projektowania? Przegrana w trybie projektowania nie jest przeszkodą, ale będzie przydatna podczas nauki XAML. Czyściciel bez łańcuchów byłby miły!
Myślę, że możliwe jest użycie AutoFac / IoC do rozdzielania viewmodels do views, jak to było w przypadku znaczników XAML podejść wyżej i zejść tą trasą?
Dzięki.1 answers
Zamiast implementować pierwszy konstruktor, proponuję zaimplementować ViewModelLocator, jak to:
public class ViewModelLocator
{
IoCContainer Container { get; set; }
public IUserViewModel UserViewModel
{
get
{
return IoCContainer.Resolve<IUserViewModel>();
}
}
}
Następnie w XAML deklarujesz lokalizator jako statyczny zasób:
<local:ViewModelLocator x:Key="ViewModelLocator"/>
Podczas inicjalizacji aplikacji, konieczne jest podanie lokalizatorowi instancji kontenera:
var viewModelLocator = Application.Current.Resources["ViewModelLocator"] as ViewModelLocator;
if(viewModelLocator == null) { // throw exception here }
viewModelLocator.Container = IoCContainer;
Następnie w XAML możesz używać zasobu czysto:
<UserControl
DataContext="{Binding Path=UserViewModel, Source={StaticResource ViewModelLocator}}"
/>
<!-- The other user control properties -->
Na czas projektowania można zaimplementować MockViewModelLocator:
public class MockViewModelLocator
{
public IUserViewModel UserViewModel
{
get
{
return new MockUserViewModel();
}
}
}
Declare it in XAML odpowiednio:
<local:MockViewModelLocator x:Key="MockViewModelLocator"/>
I na koniec użyj go w swojej kontroli użytkownika:
<UserControl
d:DataContext="{Binding Path=UserViewModel, Source={StaticResource MockViewModelLocator}}"
DataContext="{Binding Path=UserViewModel, Source={StaticResource ViewModelLocator}}"
/>
<!-- The other user control properties -->
Możesz sprawić, że lokalizator modelu mock view zwróci bezpieczne i łatwe do odczytania dane do użycia w Blend, a podczas wykonywania będziesz korzystać z prawdziwej usługi.
W ten sposób nie tracisz danych czasu projektowania i nie musisz poświęcać czystości metodologii iniekcji zależności w swoich modelach widoku.
Mam nadzieję, że to pomoże.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-27 14:27:29