Часто, когда я читаю о DI, это трактуется как все и конец всему. Я чаще всего интенсивно использую IoC даже в своих небольших и простых проектах, однако, это всего лишь шаблон и место, как и все остальное.
Книга Microsoft Press Адаптивный код с помощью C # хорошо объясняет SOLID, оправдывает его использование, охватывает различные формы DI и затраты / выгоды каждого метода. Для меня в этом много смысла: управление ростом проекта и работа с внешними зависимостями.
Я бы НЕ передавал UnityContainer
чему-либо за пределами моего загрузчика, кроме системы, которая абстрагирует и разбивает процесс начальной загрузки / модульности. В дополнение к замечаниям, которые вы сделали по этому поводу, Unity является сторонней зависимостью от вашего приложения, как и все остальное, и я бы очень избирательно отнесся к тому (если есть), к которому я себя привязываю.
Для вашего примера выше я бы использовал простую фабрику. Вы можете абстрагировать это так, как вам нравится, но хорошим компромиссом будет освобождение вашей основной ViewModel от бремени необходимости создавать своих собственных потомков.
При использовании DI нет ничего плохого в том, чтобы создавать экземпляры самостоятельно, где это уместно. Самым подходящим местом, конечно, является завод. Я бы не стал создавать универсальную фабрику, как вы сказали, это в основном похоже на обход контейнера IoC. Вместо этого определите типизированную фабрику:
public interface IWorkspaceItemViewModelFactory
{
WorkspaceItemViewModel CreateWorkspaceItem();
}
Реализация этого может выглядеть примерно так:
public class WorkspaceItemViewModelFactory
{
private readonly IWorkspaceManager _workspaceManager;
public WorkspaceItemViewModelFactory(IWorkspaceManager workspaceManager)
{
_workspaceManager = workspaceManager;
}
public WorkspaceItemViewModel CreateWorkspaceItem()
{
return new WorkspaceItemViewModel(_workspaceManager);
}
}
Этот класс является информационным экспертом с единственной ответственностью за создание WorkspaceItemViewModel
экземпляров. Он имеет право использовать ключевое слово new
и знает о WorkspaceItemViewModel
зависимостях. Возможно, вы захотите изолировать ViewModel с помощью интерфейса, но в вашем случае это значение может быть очень небольшим. В конечном счете, вы используете IoC, DI и интерфейсную сегрегацию по определенной причине, и когда они перестают приносить пользу вашему конкретному приложению, их использование становится помехой.
Ваша модель представления может использовать что-то вроде:
public class ExampleViewModel : ViewModelBase
{
public ExampleViewModel(IWorkspaceItemViewModelFactory workspaceItemViewModelFactory)
{
AddItemCommand = new ActionCommand(() =>
{
var newItem = workspaceItemViewModelFactory.CreateWorkspaceItem();
WorkspaceItems.Add(newItem);
});
}
public ICommand AddItemCommand { get; }
public ObservableCollection<WorkspaceItemViewModel> WorkspaceItems { get; } = new ObservableCollection<WorkspaceItemViewModel>();
}