本文介绍了如何避免Service Locator模式?我是不是该?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前工作的一个WinForms系统(我知道)创建表单时,那里有很多的构造器注入对的,但如果这些表单/视图需要另辟形式,我觉得DI容器已经注射过,使我们可以在运行时找到所需的视图接口的实现。 。例如

 公共部分类MyView的:形式,IMyView 
{
私人只读IDIContainer _container;

公共MyView的(IDIContainer容器)
{
的InitializeComponent();

_container =容器;
}

公共OpenDialogClick(对象发件人,EventArgs五)
{
VAR对话框= container.Resolve< IDialogView>();
dialog.ShowDialog(本);
}
}



我知道,这基本上是使用容器作为一个服务定位器。我已经多次告诉我,这被认为是一种反模式,所以我想避免这种用法。



我大概可以注入视图作为构造的一部分像这样的:

 公共部分类MyView的:形式,IMyView 
{
私人只读IDialogView _dialog;

公共MyView的(IDialogView对话)
{
的InitializeComponent();

_dialog =对话框;
}

公共OpenDialogClick(对象发件人,EventArgs五)
{
dialog.ShowDialog(本);
}
}



但是,如果对话框的看法是相当昂贵实例?



它已经建议我们创建某种形式的工厂内部使用的DI容器,但对我来说这似乎是简单地创建围绕另一个服务定位器的包装。



我知道,在某些时候,的的东西的必须知道如何创建一个IDialogView,所以我想,要么它解决了当复合根创建(可能不是如果理想有许多形式和部分或全部是创建昂贵),或复合根本身具有的方式来解决的依赖性。在这种情况下,该复合根必须具有服务定位器状依赖?但后来怎么会子窗体创建这样的对话?将它们通过,比方说,事件,打开对话框这样调用到复合



我一直针对运行起来的一个特殊问题是,容器是几乎不可能嘲笑容易。这部分是什么让我思考形式工厂的想法,即使它只是是容器周围的包装。那是一个合理的理由吗?



我也曾想过自己变成一个结?有没有通过这个简单的方法吗?或者,我只是削减结和找到的东西,对我的作品?


解决方案

Factory class:

public interface IDialogFactory {
    IDialogView CreateNew();
}

// Implementation
sealed class DialogFactory: IDialogFactory {
   public IDialogView CreateNew() {
      return new DialogImpl();
   }
}

// or singleton...
sealed class SingleDialogFactory: IDialogFactory {
   private IDialogView dialog;
   public IDialogView CreateNew() {
      if (dialog == null) {
         dialog = new DialogImpl();
      }
      return dialog;
   }
}

Your code:

public partial class MyView : Form, IMyView {
   private readonly IDialogFactory factory;
   public MyView(IDialogFactory factory) {
      InitializeComponent();
      //assert(factory != null);
      this.factory = factory;
   }

   public OpenDialogClick(object sender, EventArgs e) {
      using (var dialog = this.factory.CreateNew()) {
         dialog.ShowDialog(this);
      }
   }
}

Registration with SimpleInjector

container.RegisterSingle<IDialogFactory, DialogFactory>();

or using singleton version

container.RegisterSingle<IDialogFactory, SingleDialogFactory>();

container.RegisterSingle<IMyView, MyView>();

这篇关于如何避免Service Locator模式?我是不是该?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 21:16
查看更多