在 Collection 中创建新对象时使用 DI 的正确方法

MVVM,使用 PRISM 6 和 Unity。

Bootstrapper 负责创建初始视图,该视图又自动连接到 ViewModel(即,视图模型被解析并且它的 DI 被处理)。

现在视图模型有一个其他视图模型的集合。

这个集合可以通过用户输入添加到,比如按下按钮。

集合中的视图模型需要访问我必须管理“工作区”(图像文件夹等的路径)的单例。所以我还希望这些对象的创建能够将“工作区”单例注入其中。

在创建新 ViewModel 的方法中,使用 DI/IoC 创建它的正确方法是什么?

我看到它的唯一方式(危险地说“只有”我知道,这就是我寻求帮助的原因)是:

  1. 将 Unity Container 注入到包含集合的视图模型中,然后在按下按钮时解析新的视图模型。新的视图模型将设置为依赖于“工作区”对象的接口。

  2. 当按钮被点击时创建一个new视图模型并将“工作区”传递给构造函数(当然工作区需要被 DI 到父视图模型中才能传递下来)。

我已经阅读了多个通过 DI 将容器向下传递的地方,以便可以使用 Resolve<> 不是“正确的”。

这是创建通用工厂有帮助的地方吗?这仍然迫使我将容器向下传递,但现在它只是以工厂的形式......

public T factory<T>(IContainer _container)

{

    return _container.Resolve<T>();

}


哈士奇WWW
浏览 177回答 1
1回答

紫衣仙女

通常,当我读到 DI 时,它被视为全部和全部。即使在我的小而简单的项目中,我也经常大量使用 IoC,但是,它只是一种模式,并且和其他所有东西一样都有一席之地。Microsoft Press 的Adaptive Code via C#书很好地解释了 SOLID,证明了其使用的合理性,涵盖了 DI 的各种形式以及每种技术的成本/收益。对我来说,它对这些问题、管理项目增长和处理外部依赖关系有很大的意义。除了抽象和分解引导/模块化过程的系统之外,我不会将其传递UnityContainer给我的引导程序之外的任何东西。除了您对此提出的观点之外,Unity 是您的应用程序的第三方依赖项,就像其他任何东西一样,我会非常有选择地选择我将自己绑定到哪个(如果有的话)。对于上面的示例,我将使用一个简单的工厂。您可以随意抽象它,但一个好的折衷方案是减轻您的主要 ViewModel 必须创建自己的孩子的负担。使用 DI 时,在适当的地方自己实例化事物并没有错。最合适的地方当然是工厂。正如您所说,我不会创建通用工厂,这基本上就像传递 IoC 容器一样。而是定义一个类型化工厂:public interface IWorkspaceItemViewModelFactory{&nbsp; &nbsp; WorkspaceItemViewModel CreateWorkspaceItem();}这个的实现可能看起来像这样:public class WorkspaceItemViewModelFactory{&nbsp; &nbsp; private readonly IWorkspaceManager _workspaceManager;&nbsp; &nbsp; public WorkspaceItemViewModelFactory(IWorkspaceManager workspaceManager)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; _workspaceManager = workspaceManager;&nbsp; &nbsp; }&nbsp; &nbsp; public WorkspaceItemViewModel CreateWorkspaceItem()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return new WorkspaceItemViewModel(_workspaceManager);&nbsp; &nbsp; }}此类是信息专家,仅负责创建WorkspaceItemViewModel实例。它具有使用new关键字的权利,并且具有WorkspaceItemViewModel依赖关系的知识。您可能希望使用接口隔离 ViewModel,但在您的用例中价值可能很小。归根结底,您使用 IoC、DI 和接口隔离是有原因的,当它们停止为您的特定应用程序提供价值时,它们的使用就会变成噪音。您的视图模型可以使用以下内容:public class ExampleViewModel : ViewModelBase{&nbsp; &nbsp; public ExampleViewModel(IWorkspaceItemViewModelFactory workspaceItemViewModelFactory)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; AddItemCommand = new ActionCommand(() =>&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var newItem = workspaceItemViewModelFactory.CreateWorkspaceItem();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WorkspaceItems.Add(newItem);&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; }&nbsp; &nbsp; public ICommand AddItemCommand { get; }&nbsp; &nbsp; public ObservableCollection<WorkspaceItemViewModel> WorkspaceItems { get; } = new ObservableCollection<WorkspaceItemViewModel>();}
打开App,查看更多内容
随时随地看视频慕课网APP