C# 使用简单注入器在运行时注入数据解析模型
我正在用WPF中的Simple Injector构建一个应用程序,我遇到了一个问题,我想解决我的模型在运行时注入到我的ViewModels中的问题。例如,假设我有一个窗口来编辑需要具有用户模型的ViewModel的用户。从列表中选择此用户模型,然后将其注入ViewModel的构造函数中。如何使用Simple Injector将这些数据导入ViewModel?这可能吗?我想如果可能的话,我可能会使用某种形式的工厂?我一直在讨论使用SimpleInjector来解决除了MVVM组件之外的所有问题,除非我能找到一个好的解决方案C# 使用简单注入器在运行时注入数据解析模型,c#,wpf,mvvm,dependency-injection,simple-injector,C#,Wpf,Mvvm,Dependency Injection,Simple Injector,我正在用WPF中的Simple Injector构建一个应用程序,我遇到了一个问题,我想解决我的模型在运行时注入到我的ViewModels中的问题。例如,假设我有一个窗口来编辑需要具有用户模型的ViewModel的用户。从列表中选择此用户模型,然后将其注入ViewModel的构造函数中。如何使用Simple Injector将这些数据导入ViewModel?这可能吗?我想如果可能的话,我可能会使用某种形式的工厂?我一直在讨论使用SimpleInjector来解决除了MVVM组件之外的所有问题,除
如果我需要发布一些示例代码或类似的东西来更清楚地定义问题,请告诉我。这是我第一次使用DI容器运行,我想了解如何最好地使用DI容器设计我的应用程序。您不应该将模型注入到ViewModel中 听起来您更需要一个事件聚合器/消息聚合器。您可以将事件聚合器注入到视图模型中,订阅某个事件并将其从另一个视图模型中提升
public class CustomersViewModel
{
private readonly IEventAggregator eventAggregator;
public CustomersViewModel(IEventAggregator eventAggregator)
{
if(eventAggregator==null)
{
throw new ArgumentNullException("eventAggregator");
}
this.eventAggregator = eventAggregator;
}
private Customer selectedCustomer;
public Customer SelectedCustomer
{
get { return selectedCustomer; }
set
{
if(selectedCustomer!=value)
{
selectedCustomer = value;
eventAggregator.Publish(new CustomerSelectedEvent(selectedCustomer);
}
}
}
}
public class CustomerOrdersViewModel
{
private readonly IEventAggregator eventAggregator;
private readonly IOrderRepository orderRepository;
private ObservableCollection<Order> orders;
public ObservableCollection<Order> Orders {
get { return orders; }
set
{
if(orders != value)
{
orders = value;
OnPropertyChanged("Orders");
}
}
}
public CustomerDetailViewModel(IEventAggregator eventAggregator, IOrderRepository orderRepository)
{
if(eventAggregator==null)
{
throw new ArgumentNullException("eventAggregator");
}
this.eventAggregator = eventAggregator;
this.eventAggregator.Subscribe<CustomerSelectedEvent>(OnCustomerSelected);
...
}
private async void OnCustomerSelected(CustomerSelectedEvent event)
{
Orders = new ObservableCollection<Order>(await orderRepository.GetOrdersByCustomer(event.Customer.Id);
}
}
事件聚合器的实现有点超出了范围,但是messanger/event聚合器(例如Prism PubSubEvents)附带了一些框架。您不应该将模型注入到ViewModel中 听起来您更需要一个事件聚合器/消息聚合器。您可以将事件聚合器注入到视图模型中,订阅某个事件并将其从另一个视图模型中提升
public class CustomersViewModel
{
private readonly IEventAggregator eventAggregator;
public CustomersViewModel(IEventAggregator eventAggregator)
{
if(eventAggregator==null)
{
throw new ArgumentNullException("eventAggregator");
}
this.eventAggregator = eventAggregator;
}
private Customer selectedCustomer;
public Customer SelectedCustomer
{
get { return selectedCustomer; }
set
{
if(selectedCustomer!=value)
{
selectedCustomer = value;
eventAggregator.Publish(new CustomerSelectedEvent(selectedCustomer);
}
}
}
}
public class CustomerOrdersViewModel
{
private readonly IEventAggregator eventAggregator;
private readonly IOrderRepository orderRepository;
private ObservableCollection<Order> orders;
public ObservableCollection<Order> Orders {
get { return orders; }
set
{
if(orders != value)
{
orders = value;
OnPropertyChanged("Orders");
}
}
}
public CustomerDetailViewModel(IEventAggregator eventAggregator, IOrderRepository orderRepository)
{
if(eventAggregator==null)
{
throw new ArgumentNullException("eventAggregator");
}
this.eventAggregator = eventAggregator;
this.eventAggregator.Subscribe<CustomerSelectedEvent>(OnCustomerSelected);
...
}
private async void OnCustomerSelected(CustomerSelectedEvent event)
{
Orders = new ObservableCollection<Order>(await orderRepository.GetOrdersByCustomer(event.Customer.Id);
}
}
事件聚合器的实现有点超出了范围,但messanger/event aggregators(例如Prism PubSubEvents)附带了一些框架。使用首选方法确实不可能实现您的目标。这是因为你的设计不是最优的。正如您可以读取的那样,在应用程序的组件中注入运行时数据是一种反模式 编辑用户的模型是运行时数据,因此应该通过方法注入在应用程序中流动 所以你可以这样解决这个问题:
public interface IViewModel<T>
{
void EditItem(T item);
}
class UserEditViewModel : IViewModel<User>
{
public void EditItem(User item)
{
// bind properties etc...
}
}
现在,只要在需要编辑某个模型的任何地方插入IEditProcessor
并调用
this.editProcessor.EditItem(yourItem);
EditProcessor
的这个简单实现可以扩展各种功能,例如在编辑之前备份项目,因此用户可以取消editform
如果您使用一些MVVM工具包将视图绑定到viewmodel,那么这也将是您的DI容器和MVVM工具包能够很好地相互交互的地方 使用你想要的首选方法确实是不可能的。这是因为你的设计不是最优的。正如您可以读取的那样,在应用程序的组件中注入运行时数据是一种反模式 编辑用户的模型是运行时数据,因此应该通过方法注入在应用程序中流动 所以你可以这样解决这个问题:
public interface IViewModel<T>
{
void EditItem(T item);
}
class UserEditViewModel : IViewModel<User>
{
public void EditItem(User item)
{
// bind properties etc...
}
}
现在,只要在需要编辑某个模型的任何地方插入IEditProcessor
并调用
this.editProcessor.EditItem(yourItem);
EditProcessor
的这个简单实现可以扩展各种功能,例如在编辑之前备份项目,因此用户可以取消editform
如果您使用一些MVVM工具包将视图绑定到viewmodel,那么这也将是您的DI容器和MVVM工具包能够很好地相互交互的地方 有趣的方法。我认为我的概念在某种程度上是有缺陷的,但我不确定如何或以一种好的方式来取代它。谢谢如何使用这种方法显示用于编辑用户的模式对话框?这是一个棘手的部分。一种方法是使用对话框或导航服务,在ViewModel层中传递接口,并在视图/应用程序集中执行具体实现(假设您通过将应用程序拆分为至少3个模型、视图模型和视图/应用程序集来实施MVVM)。另一种方法是在Prism 5.0/6.0框架中看到的,InteractionRequest很难开始使用,但是一旦你掌握了itOr,就可以非常强大,只需使用我的答案中的EditProcessor之类的基础结构组件。使事情简单且独立于各种框架。我在EditProcessor中注入了一个DialogHandler并从那里启动。这是一个有趣的方法。我认为我的概念在某种程度上是有缺陷的,但我不确定如何或以一种好的方式来取代它。谢谢如何使用这种方法显示用于编辑用户的模式对话框?这是一个棘手的部分。一种方法是使用对话框或导航服务,在ViewModel层中传递接口,并在视图/应用程序集中执行具体实现(假设您通过将应用程序拆分为至少3个模型、视图模型和视图/应用程序集来实施MVVM)。另一种方法是在Prism 5.0/6.0框架中看到的,InteractionRequest很难开始使用,但是一旦你掌握了itOr,就可以非常强大,只需使用我的答案中的EditProcessor之类的基础结构组件。使事情简单且独立于各种框架。我在EditProcessor中注入了一个DialogHandler并从那里启动。我确实有一个问题。你认为我是如何将我的观点与这个模型结合起来的?假设我有一个带有接受IViewModel的构造函数的窗口,我应该如何连接所有内容,还是应该让视图模型引用该窗口?我偶尔也看到过这种情况。我不使用MVVM工具包,所以我需要手动解决这些问题。给定某个ViewModel,您如何为它找到正确的视图?你有什么惯例吗?我猜,根据你的问题,你不知道。有几种方法可以做到这一点。如果你给我一些指导,我可以用一些例子来编辑我的答案