Reputation: 1337
I'm using C#.Net, but any relevant example is very much acceptable.
I have 2 winforms, let's say ListFrm and DetailFrm, in which everytime user click on a button in DetailFrm, a new ListFrm will popup so user can change the selected item.
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;
}
}
My problem is when I clicked on DetailFrm's browse button for the second time, ListFrm wouldn't load because it's already disposed of.
How to do this with dependency injection? I can't create a ListFrmFactory because it can't create a new ListFrm which requires an ItemRepository dependency.
I also don't want to pass around the DIContainer everywhere since it would be a service locator.
If it done without dependency injection, I would just call new ListFrm()
everytime I need it.
Thanks !
Upvotes: 0
Views: 398
Reputation: 3393
Rather than inject the ListFrm, inject a ListFrmFactory. Have the ListFrmFactory take the ListRepository as an injected dependency. Then your factory can of course build a new ListFrm whenever it is needed, passing in the repository directly.
Upvotes: 0
Reputation: 14578
You can use delegate injection to handle this scenario. This will enable you to keep your Container configuration in one place and create get a new instance each time it's required.
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
}
}
}
Upvotes: 3
Reputation: 631
Do not dispose form. Just hide it!
Use this method:
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.hide.aspx
notice Form inherits it from Control
Upvotes: 0
Reputation: 554
I didn't find out what are you gonna do , Here you just need to close your list form instead of dispose it, you have just one instance of it in your detail form so when you dispose it, you couldn't use it in next time, If you want to make Loosely coupled dependency between your forms classes you should define an interface and your listForm should implement it and in your detailForm you must have an instance of you listForm in type of you interface for more info you can take look at this article from MSDN : Dependancy Injection
Upvotes: 0