如何使用依赖注入多次创建对象
Posted
技术标签:
【中文标题】如何使用依赖注入多次创建对象【英文标题】:How to create object more than once with dependency injection 【发布时间】:2013-05-16 07:30:02 【问题描述】:我使用的是 C#.Net,但任何相关示例都可以接受。
我有 2 个 winform,比如说 ListFrm 和 DetailFrm,其中每次用户单击 DetailFrm 中的按钮时,都会弹出一个新的 ListFrm,以便用户可以更改所选项目。
DetailFrm.cs
public class DetailFrm
private readonly ListFrm _listFrm;
public DetailFrm(ListFrm listFrm)
_listFrm = listFrm;
private SelectButton OnClick(object sender, EventArgs e)
using(listFrm)
listFrm.ShowDialog();
// Do detail data filling here
ListFrm.cs
public class ListFrm
public Item SelectedItem get; set;
private readonly ListRepository _listRepository;
public ListFrm(ListRepository listRepository)
_listRepository = listRepository;
private ListFrm_Load(object sender, EventArgs e)
List<Item> listItem = _listRepository.GetAll();
// Do adding to datagridview
private dataGridViewSelect_CellDoubleClick(object sender, EventArgs e)
SelectedItem = // Selected in datagridview
this.Dispose;
我的问题是当我第二次点击 DetailFrm 的浏览按钮时,ListFrm 无法加载,因为它已经被处理掉了。
如何使用依赖注入来做到这一点?我无法创建 ListFrmFactory,因为它无法创建需要 ItemRepository 依赖项的新 ListFrm。
我也不想到处传递 DIContainer,因为它会是一个服务定位器。
如果在没有依赖注入的情况下完成,我会在每次需要时调用new ListFrm()
。
谢谢!
【问题讨论】:
为什么要处理表单? 你为什么要这样处理ListFrm
实例?
好吧,选择第二次实际上并不是必需的情况,而只是为了适应这种可能性。而且我认为不再需要时无需维护资源消耗形式。我应该隐藏它吗?
【参考方案1】:
您可以使用委托注入来处理这种情况。这将使您能够将 Container 配置保存在一个位置,并在每次需要时创建一个新实例。
public class DetailFrm
private readonly Func<ListFrm> _listFrmInstance;
public DetailFrm(Func<ListFrm> listFrmInstance)
_listFrmInstance = listFrmInstance;
private SelectButton OnClick(object sender, EventArgs e)
using(var listFrm = _listFrmInstance())
listFrm.ShowDialog();
// Do detail data filling here
【讨论】:
【参考方案2】:我不知道你要做什么, 在这里你只需要关闭你的列表表单而不是处理它, 您的详细信息表单中只有一个实例,因此当您处理它时,下次无法使用它, 如果你想在你的表单类之间建立松散耦合的依赖关系,你应该定义一个接口,你的 listForm 应该实现它,并且在你的 detailForm 中,你必须有一个 listForm 的实例,类型为你的接口以获取更多信息,你可以看看这篇文章来自 MSDN: Dependancy Injection
【讨论】:
好吧,我想这是我的缺陷。那么,如果我处置了 DetailFrm,ListFrm 也会被处置吗?因为我不喜欢占用不应该存在的内存资源的想法。 当然它也会dispose,当GC迭代抛出对象时,当它发现没有人指向的东西时,它会从内存中删除它。 另一方面,您可以覆盖您的 detailForm 的 dispose 方法并手动调用您的 listForm dispose 方法,但是它有一些技巧来覆盖 win Form 的 dispose 方法,因为设计师之前已经覆盖了它,如何我们可以覆盖 win 表单的 dispose 方法吗?您可以阅读这篇文章:***.com/questions/1052147/…【参考方案3】:不要丢弃表单。把它藏起来!
使用这个方法:
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.hide.aspx
通知Form继承自Control
【讨论】:
【参考方案4】:与其注入 ListFrm,不如注入一个 ListFrmFactory。让 ListFrmFactory 将 ListRepository 作为注入依赖项。然后你的工厂当然可以在需要时构建一个新的 ListFrm,直接传入存储库。
【讨论】:
我试图创建一个工厂,但我最终需要再次手动提供 ListFrm 依赖项。所以我认为这不是最好的解决方案。以上是关于如何使用依赖注入多次创建对象的主要内容,如果未能解决你的问题,请参考以下文章
依赖注入(Dependency Injection)框架是如何实现的?