wpf - 如何在运行时在 Prism 中注入新实例?
问题描述
我将 Prism 7.1 用于 WPF 应用程序。我尝试使用内置的 IOC(Unity),但我不知道如何在运行时从方法或 containerProvider 解析新实例。但似乎 IContainerProvider 无法注入到我的视图模型中。我有什么选择吗?
我想这样做以重新加载我的数据库上下文。有人告诉我,创建新的上下文是最简单的。
public class ProjectViewModel : BindableBase
{
private UnitOfWork unitOfWork;
private IContainerProvider containerProvider;
private IEventAggregator eventAggregator;
#region Constructor
public ProjectViewModel(UnitOfWork unitOfWork, IContainerProvider cp, IEventAggregator ea)
{
this.unitOfWork = unitOfWork;
containerProvider = cp;
eventAggregator = ea;
eventAggregator.GetEvent<SendReloadDataEvents>().Subscribe(Reload);
Reload();
}
#endregion
private void Reload()
{
this.unitOfWork = containerProvider.Resolve<UnitOfWork>();
Projects = new ObservableCollection<Projects>(unitOfWork.ProjectRepo.GetAll());
Customers = new ObservableCollection<Customers>(unitOfWork.CustomerRepo.Find(x => x.Projects.Count > 0));
SelectedProjectType = null;
}
//Other logic continues
}
解决方案
注入容器是一种反模式,因此我们将尝试避免这种情况并改为注入工厂。实际上,IContainerProvider
并IContainerRegistry
没有为此注册自己,以使其无法注入。
工厂很容易:
public class ProjectViewModel : BindableBase
{
private UnitOfWork unitOfWork;
private Func<UnitOfWork> unitOfWorkFactory;
private IEventAggregator eventAggregator;
#region Constructor
public ProjectViewModel(Func<UnitOfWork> unitOfWorkFactory, IEventAggregator ea) // no need to inject a unit of work
{
_unitOfWorkFactory = unitOfWorkFactory;
eventAggregator = ea;
ea.GetEvent<SendReloadDataEvents>().Subscribe(Reload); // prefer the parameter
Reload();
}
#endregion
private void Reload()
{
this.unitOfWork = _unitOfWorkFactory(); // create a new one here (the container does the work but is hidden)
Projects = new ObservableCollection<Projects>(unitOfWork.ProjectRepo.GetAll()); // I'd rather update the existing collection
Customers = new ObservableCollection<Customers>(unitOfWork.CustomerRepo.Find(x => x.Projects.Count > 0)); // same here, or probably, it could just be IEnumerable
SelectedProjectType = null;
}
//Other logic continues
}
请注意,该Func<>
工厂仅适用于最简单的情况。如果您需要将参数传递到产品构造函数中,则必须按照此答案中的描述自行编写代码。还要注意容器是如何从不出现在任何地方的(除了它被配置的地方),让你的代码依赖于容器是不必要的,并且会使测试更加难看。
推荐阅读
- postgresql - 带有下划线的 JPA 列 - CustomPhysicalNamingStrategy 正在抛出 NullPointer exeption
- c# - 在 SSIS / C# 中确定大文件的文件编码
- javascript - 如何获取客户端 ASP.NET 上已安装程序的列表
- php - WooCommerce wc_price($price) & 变化 & 头痛
- angular - Angular,拖放,在拖动元素时更改文本
- bash - 如何使用 bash 命令更改 yaml 文件中的值?
- sharding - MemSQL 中的分片键可以有 NULL 吗?
- microsoft-graph-api - 365 团队聊天的 Graph API 限制为每个聊天 20 条消息
- google-cloud-dataprep - Combine multiple rows into single row in Google Data Prep
- django - 如何在 django simple jwt 中自定义登录 url 和条件