Я просто пишу класс, реализующий шаблон ServiceLocator.
public class ServiceFactory : IServiceFactory
{
private IDictionary<Type, object> instantiatedServices;
public ServiceFactory()
{
instantiatedServices = new Dictionary<Type, object>();
}
public T GetService<T>() where T : class, new()
{
if (this.instantiatedServices.ContainsKey(typeof(T)))
{
return (T)this.instantiatedServices[typeof(T)];
}
else
{
T service = new T();
instantiatedServices.Add(typeof(T), service);
return service;
}
}
}
Теперь у меня есть несколько вопросов:
1.) Откуда мне вызвать этот класс?app.xaml.cs делает вещи wpf?
2.) Должен ли я регистрировать службы, если да, где мне это делать?
3.) Когда я выполняю ленивую инициализацию службы "ICustomerService ", почему тогда я должен создать метод Register (T service) для него?это двойная работа.
4.) Стоит ли мне вообще искать сервисный локатор?
ОБНОВЛЕНИЕ
В данный момент я чувствую, что долженИзнасиловать DI-инструмент для моих индивидуальных целей, которые являются =>
App.xaml.cs => Здесь я создаю MainWindow и устанавливаю его текст данных в MainViewModel.cs
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
var mainVM = new MainViewModel();
var mainWindow = new MainWindow();
mainWindow.DataContext = mainVM;
mainWindow.ShowDialog();
}
}
MainViewModel.cs => Здесь я предварительно загружаю / настраиваю данные, которые мне нужны для определенных Controller / ViewModel, таких как LessonPlannerDailyViewModel или LessonPlannerWeeklyViewModel и т. Д. *
public class MainViewModel : SuperViewModel
{
private LightCommand _newSchoolYearWizardCommand;
private LightCommand _showSchoolclassAdministrationCommand;
private LightCommand _showLessonPlannerDailyCommand;
private LightCommand _showLessonPlannerWeeklyCommand;
private LightCommand _openSchoolYearWizardCommand;
private SuperViewModel _vm;
private FadeTransition _fe = new FadeTransition();
private readonly IMainRepository _mainService;
private readonly ILessonPlannerService _lessonPlannerService;
private readonly IAdminService _adminService;
private readonly IDocumentService _documentService;
private readonly IMediator _mediator;
private readonly IDailyPlanner _dailyVM;
private readonly IWeeklyPlanner _weeklyVM;
private SchoolclassAdministrationViewModel _saVM;
public MainViewModel()
{
// These are a couple of services I create here because I need them in MainViewModel
_mediator = new Mediator();
_mainService = new MainRepository();
_lessonPlannerService = new LessonPlannerService();
_adminService = new AdminService();
_documentService = new DocumentService();
this._mediator.Register(this);
InitSchoolclassAdministration();
}
//... Create other ViewModel/Controller via button commands and their execute method
}
Вкл.другой видовой моделью является LessonPlannerDailyViewModel.cs => Здесь я создаю привязываемую коллекцию объектов PeriodViewModel, которые принимают в своем конструкторе некоторые службы.В следующем абзаце после следующего кода см. DocumentListViewModel.cs, созданный ONE PeriodViewModel, который снова принимает службы - то же, что я создал в MainViewModel ... -
public class LessonPlannerDailyViewModel : LessonPlannerBaseViewModel, IDailyPlanner
{
private ILessonPlannerService _lpRepo;
private IMainRepository _mainRepo;
private IMediator _mediator;
private IDocumentService _docRepo;
private ObservableCollection<PeriodViewModel> _periodListViewModel;
private LightCommand _firstDateCommand;
private LightCommand _lastDateCommand;
private LightCommand _nextDateCommand;
private LightCommand _previousDateCommand;
public LessonPlannerDailyViewModel(IMediator mediator, ILessonPlannerService lpRepo, IMainRepository mainRepo, IDocumentService docRepo)
{
_mediator = mediator;
_lpRepo = lpRepo;
_mainRepo = mainRepo;
_docRepo = docRepo;
_mediator.Register(this);
SchoolYear schoolyear = _mainRepo.GetSchoolYear();
MinDate = schoolyear.Start;
MaxDate = schoolyear.End;
SelectedDate = DateTime.Now;
}
private void LoadLessonPlannerByDay(DateTime data)
{
_periodListViewModel = new ObservableCollection<PeriodViewModel>();
_lpRepo.GetLessonPlannerByDay(data).ForEach(p =>
{
_periodListViewModel.Add(new PeriodViewModel(p, _lpRepo, _docRepo));
});
PeriodListViewModel = _periodListViewModel;
}
private DateTime _selectedDate;
public DateTime SelectedDate
{
get { return _selectedDate; }
set
{
if (_selectedDate.Date == value.Date)
return;
_selectedDate = value;
this.RaisePropertyChanged("SelectedDate");
LoadLessonPlannerByDay( value );
}
}
// ...
}
PeriodViewModel.cs => Каждая DataRow в моей DataGrid имеет Период, а Период имеет определенную ячейку данных, преобразованную в DocumentListViewModel - Период 1 имеет N Документов, это отношение FYI ... поэтому PeriodViewModel создает DocumentListViewModel.
public class PeriodViewModel : SuperViewModel
{
private Period _period;
private ILessonPlannerService _lpRepo;
public PeriodViewModel(Period period, ILessonPlannerService lpRepo, IDocumentService docRepo)
{
_period = period;
_lpRepo = lpRepo;
// Update properties to database
this.PropertyChanged += (o, e) =>
{
switch (e.PropertyName)
{
case "Homework": _lpRepo.UpdateHomeWork(PeriodNumber, LessonDayDate, Homework); break;
case "Content": _lpRepo.UpdateContent(PeriodNumber, LessonDayDate, Content); break;
}
};
Documents = new DocumentListViewModel(_period.Id, period.Documents, docRepo);
}
//...
}
DocumentListViewModel.cs => Здесь я настраиваю команды для добавления / удаления / открытия документа, и это можно сделать с помощью documentService / documentRepository
public class DocumentListViewModel : SuperViewModel
{
private LightCommand _deleteDocumentCommand;
private LightCommand _addDocumentCommand;
private LightCommand _openDocumentCommand;
private int _parentId;
private readonly IDocumentService _documentService;
public DocumentListViewModel(int parentId,ObservableCollection<Document> documents, IDocumentService documentService)
{
_parentId = parentId;
_documentService = documentService;
DocumentList = documents;
SelectedDocuments = new ObservableCollection<Document>();
}
// ...
}
Чтобы подвести итог проблемы:Видите ли вы цепочку объектов, каскадирующих сервисы сверху:
MainViewodel -> LessonPlannerDailyViewModel -> PeriodViewModel -> DocumentListViewModel
Мне нужно каскадировать их, потому что если я не использую статический локатор службЯ могу убедиться, что один экземпляр службы только когда якаскадирование сервисов ...
Как инструмент DI может помочь мне КОНКРЕТНО в создании приложения wpf по шаблону MVVM?