提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
翻译|行业资讯|编辑:龚雪|2022-05-30 10:21:29.753|阅读 193 次
概述:本文主要介绍WPF MVVM应用程序中的依赖注入并演示如何设置,欢迎下载相关工具体验~
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
当解决方案的规模和范围扩大时,保持整体应用程序的灵活性变得更加困难。 对象之间的依赖关系不断增长,更改一个类可能需要更新其他类,依赖注入 (DI) 可以帮助解决这一挑战。
如您所知,依赖注入是“控制反转”(IoC)编程原理的一种形式。 这意味着类不会创建它们所依赖的对象,DI 框架具有负责揭示和解决依赖关系的容器。
假设您有一个使用数据服务获取数据的视图模型:
public class UserViewModel { MyDataService dataService; public UserViewModel() { this.dataService = new MyDataService(); } }
视图模型依赖于一个服务——这意味着 MyDataService 是 UserViewModel 的依赖,直接在视图模型类中创建服务非常容易,但是这种方法有几个缺点:
如果将 MyDataService 传递给 UserViewModel 的构造函数,则可以避免这些问题:
public class UserViewModel { MyDataService dataService; public UserViewModel(MyDataService dataService) { this.dataService = dataService; } }
不幸的是,这种技术也有缺陷:
依赖注入的主要思想是集中解决所有依赖,这意味着您的程序中有一个单独的块来初始化新的类实例并将参数传递给它们。 尽管您可以为此实现自己的逻辑,但使用 DI 框架来帮助避免/消除示例代码会更方便。
依赖注入模式具有以下优点:
.NET 社区有许多很棒的框架来帮助您在应用程序中实现依赖注入模式,所有这些框架都有两个主要特点:
容器是 DI 框架中的中心对象,可以自动检测和解决类依赖关系。 某些框架可以将参数注入类属性,但最常见的方法是将参数注入构造函数。
让我们修改 MainViewModel 构造函数,使其接受接口替代类:
public class MainViewModel { IDataService dataService; public MainViewModel(IDataService dataService) { this.dataService = dataService; } }
这将允许您在将来使用不同的 IDataService 实现。
进行此更改后,我们需要创建一个 DI 容器来注册 MyDataService 并实例化 MainViewModel:
protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); var builder = new ContainerBuilder(); //allow the Autofac container resolve unknown types builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource()); //register the MyDataService class as the IDataService interface in the DI container builder.RegisterType<MyDataService>().As<IDataService>().SingleInstance(); IContainer container = builder.Build(); //get a MainViewModel instance MainViewModel mainViewModel = container.Resolve<MainViewModel>(); }
在此示例中,我们使用了 Autofac 框架,但您可以使用任何其他 DI 框架,例如 Unity 或 Ninject。 DI 容器创建 MainViewModel 并自动将 MyDataService 注入 MainViewModel 构造函数,这允许您在每次创建具有 IDataService 参数类型的类时避免 MyDataService 初始化。
然后我们需要将 MainViewModel 连接到它的视图:MainView,最明显的策略是在视图构造函数中设置 DataContext:
public MainView() { InitializeComponent(); this.DataContext = container.Resolve<MainViewModel>(); }
但是,要访问 DI 容器,您必须将其设为静态或将其传递给每个视图构造函数。 一个更好的解决方案是创建一个标记扩展,它根据其类型返回一个视图模型实例:
public class DISource : MarkupExtension { public static Func<Type, object> Resolver { get; set; } public Type Type { get; set; } public override object ProvideValue(IServiceProvider serviceProvider) => Resolver?.Invoke(Type); }
<UserControl DataContext="{local:DISource Type=local:MainViewModel}">
最初,标记扩展未绑定到任何 DI 容器。 要允许扩展使用您的容器,请按以下方式指定视图模型解析器:
public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); //... IContainer container = builder.Build(); DISource.Resolver = (type) => { return container.Resolve(type); }; } }
这种技术允许 DISource 与任何可能的容器一起工作。
在上面的示例中,我们使用了不与可视控件通信的抽象数据服务。 如您所知,许多DevExpress WPF服务使用视图控件,因此服务必须知道使用哪个控件。 例如,如果您希望将 NavigationFrameService 注入到视图模型中,还需要将此服务附加到相应的 NavigationFrame 控件。
在视图模型中创建一个包含服务的公共属性,并将服务绑定到 NavigationFrame:
public class MainViewModel { public INavigationService NavigationService { get; } public MainViewModel(INavigationService navigationService) => NavigationService = navigationService; }
<dxwui:NavigationFrame> <dxmvvm:Interaction.Behaviors> <common:AttachServiceBehavior Service="{Binding NavigationService}"/> </dxmvvm:Interaction.Behaviors> </dxwui:NavigationFrame>
AttachServiceBehavior 是一个简单的附加操作,它在服务属性更改时调用 NavigationFrameService.Attach。 虽然 AttachServiceBehavior 不包含在我们的库中,但您可以在此处获取其代码:。即使 MainViewModel 使用 NavigationFrameService,它也不必实现 ISupportServices 接口。 此外,导航中涉及的所有子视图都可以在不附加到 NavigationFrame 的情况下使用该服务——因为它已经在主视图级别进行了配置。
并非所有DevExpress 服务都需要可视化组件,某些服务,例如 或 ,不需要显式附加,因此您可以将它们作为任何其他非 DevExpress 服务注入。
在某些情况下,如果需要为特定视图配置服务,则使用 DI 容器注入服务可能并不明智。 例如,如果您有一个绑定到视图模型命令的服务,就会出现这种情况,直接在视图中定义服务并在那里配置所有绑定要容易得多。
DevExpress WPF拥有120+个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件的衍伸产品,还是以数据为中心的商业智能产品,都能通过DevExpress WPF控件来实现。
DevExpress技术交流群6:600715373 欢迎一起进群讨论
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@cahobeh.cn
文章转载自:慧都网通过提供强大的3D CAD数据访问工具并适用于桌面、移动和Web的高级环境3D可视化发动机,HOOPS在提升造船设计和制造流程的效率方面发挥了重要作用。
HOOPS Luminate在汽车行业中的应用具有广泛的潜力和深远的影响。它通过提供高效的3D可视化、虚拟装配与拆解、性能分析、客户定制等功能,帮助汽车制造商在设计、生产和销售过程中提升效率、降低成本并提高产品质量。
在不断发展的软件开发世界中,使工具和框架与最新的平台版本保持同步至关重要,欢迎查阅~
全球航运业对国际贸易至关重要,全球 90% 以上的商品通过海运运输。准确监控和控制这些集装箱的移动对于维持高效的供应链至关重要。手动输入集装箱号码是这一程序的关键部分,它带来了相当大的挑战,例如人为错误和效率低下。
行业领先的界面控件开发包,帮助企业构建卓越应用!
DevExpress DXperience Subscription高性价比的企业级.NET用户界面套包,助力企业创建卓越应用!
DevExpress WPF Subscription高效MVVM开发模式,WPF界面解决方案首选工具,帮助企业实现酷炫动效界面。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@cahobeh.cn
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢