为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
哈士奇WWW 2022-01-16 16:19:04
MVVM,使用 PRISM 6 和 Unity。Bootstrapper 负责创建初始视图,该视图又自动连接到 ViewModel(即,视图模型被解析并且它的 DI 被处理)。现在视图模型有一个其他视图模型的集合。这个集合可以通过用户输入添加到,比如按下按钮。集合中的视图模型需要访问我必须管理“工作区”(图像文件夹等的路径)的单例。所以我还希望这些对象的创建能够将“工作区”单例注入其中。在创建新 ViewModel 的方法中,使用 DI/IoC 创建它的正确方法是什么?我看到它的唯一方式(危险地说“只有”我知道,这就是我寻求帮助的原因)是:将 Unity Container 注入到包含集合的视图模型中,然后在按下按钮时解析新的视图模型。新的视图模型将设置为依赖于“工作区”对象的接口。当按钮被点击时创建一个new视图模型并将“工作区”传递给构造函数(当然工作区需要被 DI 到父视图模型中才能传递下来)。我已经阅读了多个通过 DI 将容器向下传递的地方,以便可以使用 Resolve<> 不是“正确的”。这是创建通用工厂有帮助的地方吗?这仍然迫使我将容器向下传递,但现在它只是以工厂的形式......public T factory<T>(IContainer _container){    return _container.Resolve<T>();}
查看完整描述

1 回答

?
紫衣仙女

TA贡献1839条经验 获得超15个赞

通常,当我读到 DI 时,它被视为全部和全部。即使在我的小而简单的项目中,我也经常大量使用 IoC,但是,它只是一种模式,并且和其他所有东西一样都有一席之地。


Microsoft Press 的Adaptive Code via 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>();

}


查看完整回答
反对 回复 2022-01-16
  • 1 回答
  • 0 关注
  • 176 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信