【问题标题】:Passing Parameters across Classes using Ninject使用 Ninject 跨类传递参数
【发布时间】:2012-06-17 00:58:23
【问题描述】:

我对使用依赖注入非常陌生,我正在我的 WPF 应用程序中尝试使用 Ninject。我想知道我应该如何跨类传递参数。

例如

public class ViewPersonViewModel : ViewModelBase
{
    private IDataAccessService _dataService;
    private IPerson _person;
    private string _remarks;

    // binded to textbox
    public string Remarks
    {
        get { return _remarks; }
        set {
            if (_remarks != value) {
                remarks = value;
                OnPropertyChanged("Remarks");
            }
        }   
    }

    public ViewPersonViewModel(
        IDataAccessService dataService, IPerson person)
    {
        _dataService= dataService;
        _person = person;
    }

    // binded to Button
    public void RetrieveStatus()
    {
        Remarks = _dataService.RetrieveRemarks(_person);
    }
}

这里的dataService是一个固定的类,我想必能做到

class Module : Ninject.Modules.NinjectModule 
{
    public override void Load() 
    {
        Bind<IDataAccessService>().To<DefaultDataAccessService>();
    }
}

但我想知道我应该如何处理 person 参数,它是由调用类设置的。

我从Creating an instance using Ninject with additional parameters in the constructor看到,可以在构造函数中传递额外的参数。

但是,我有一些担忧:

  1. 使用kernel.Get&lt;MyClass&gt;( With.Parameters.ConstructorArgument( "parameterName", parameterValue) ); 是一种理想的方式吗?会不会在调试中造成很多问题,比如你误输入了parameterName

  2. Ruben 还提到了在涉及 Provider 的情况下使用更复杂的方式。在这里适用吗?如果是,我该如何使用它?

【问题讨论】:

  • 为什么你的视图模型中有这些服务?您的视图模型应该只包含数据,而不是行为。这是问题的根本原因,因为您将数据与行为混合在一起,这是使用依赖注入时失败的一般原因。
  • 我打算让这个 viewModel 利用 DefaultDataAccessService 来获取要显示的数据(字符串备注)。如果它不应该在这里,我应该把它放在哪里?
  • 您可以将其放入您的表单/页面类中,甚至可以将其提取到您在页面中加载的服务类中。
  • 但是我也在尝试遵循 mvvm 模式,并且视图类中不会有任何代码。而且我已经将它提取到 DataAccessService 类。我不确定你在提议什么。
  • 如果视图类中没有任何代码,为什么它有依赖关系? RetrieveStatus() 方法在我看来就像代码。

标签: c# .net mvvm dependency-injection ninject


【解决方案1】:

你可能会考虑像这样重载构造函数:

public ViewPersonViewModel(IPerson person)
    this(DependencyResolver.GetInstance<IDataAccessService>(), person)
{
}

public ViewPersonViewModel(
    IDataAccessService dataService, IPerson person)
{
    _dataService= dataService;
    _person = person;
}

这样做的主要缺点是您不能直接通过 IoC 请求 ViewPersonViewModel。

【讨论】:

    【解决方案2】:

    Ninject 3 提供了一个方便的函数,允许我跨类传递参数。通过创建像

    这样的接口
    public interface IViewPersonViewModelFactory()
    {
        IViewPersonViewModel CreateViewPersonViewModel([parameterType parameterName..]);
    }
    

    并将以下内容添加到要加载的 Ninject 模块中:

    public override void Load()
    {
        Bind<IMainControllingViewModelFactory>().ToFactory();
        ... ... //other bindings
    }
    

    然后我们可以获取 ViewPersonViewModel 类的实例(例如在 MainViewModel 类中)

     public class MainViewModel
     {
         private IViewPersonViewModel _viewModel;
    
         public MainViewModel(IViewPersonViewModelFactory viewModelFactory)
         {
             _viewModel = viewModelFactory.CreateViewPersonViewModel(parameters..);
         }
     }
    

    请注意,不必创建具体工厂。

    可以在以下位置找到 wiki:https://github.com/ninject/ninject.extensions.factory/wiki/Factory-interface

    【讨论】:

      猜你喜欢
      • 2011-08-09
      • 2014-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-08
      相关资源
      最近更新 更多