C# 使用简单注入器在运行时注入数据解析模型

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组件之外的所有问题,除

我正在用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,您如何为它找到正确的视图?你有什么惯例吗?我猜,根据你的问题,你不知道。有几种方法可以做到这一点。如果你给我一些指导,我可以用一些例子来编辑我的答案