0

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 !

Samuel Adam
  • 1,327
  • 4
  • 26
  • 45

4 Answers4

3

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
        }
    }
}
qujck
  • 14,388
  • 4
  • 45
  • 74
0

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

hm1984ir
  • 554
  • 3
  • 7
  • Well yeah I guess it's my flaw. So if I disposed DetailFrm, will ListFrm get disposed as well? Since I don't like the idea of something taking memory resource that shouldn't be there. – Samuel Adam May 16 '13 at 08:13
  • of course it'll dispose too , when GC iterate throw object when it find something which nobody point to, it remove it from memory. – hm1984ir May 16 '13 at 08:48
  • on the other hand you can override dispose method of your detailForm and call your listForm dispose method manually, but it has some trick to override dispose method of win Form because designer has already override it before , to how can we override dispose method of a win form you can read this post : http://stackoverflow.com/questions/1052147/how-do-i-extend-a-winforms-dispose-method – hm1984ir May 16 '13 at 08:56
0

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

Sarrus
  • 586
  • 7
  • 21
0

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.

Facio Ratio
  • 3,373
  • 1
  • 16
  • 18
  • I tried to create a factory, but I ended needing to supply ListFrm dependencies manually again. So I think it's not the best solution. – Samuel Adam May 17 '13 at 01:38