2
votes

I am trying to startup an simple Model View Presenter WinForms application and use the constructor injection to inject IMainView, IEventPublisher and IRepository to the main presenter.

However, I am having some problems to find out how to exactly do this. My problem is that for some reason presenter seems to create two instances of the view or view is created and not shown.

Program.cs

  var kernel = new StandardKernel();
  kernel.Load(Assembly.GetExecutingAssembly());
  //var view = kernel.Get<View.MainForm>();
  var presenter = kernel.Get<Presenter>();

  //Application.Run(view);
  Application.Run();

If view is initialized on the program.cs, then also presenter creates its own view? And with the active approach above, the view is created but not shown.

Presenter.cs

public Presenter(IMainForm view,
  IRepository repository,
  IEventPublisher eventPublisher)
{
  _view = view;
  _repository = repository;
  _reactiveEventPublisher = eventPublisher;
}

MainForm.cs

public Form(IEventPublisher eventPublisher)
{
  _reactiveEventPublisher = eventPublisher;
}

NinjectBindings.cs

  public class NinjectBindings : NinjectModule
  {
    public override void Load()
    {
      Bind<IRepository>().To<Repository>();

      Bind<IMainForm>().To<View.MainForm>();

      Bind<IEventPublisher>().To<ReactiveEventAggregator>().InSingletonScope();

      Bind<Presenter>().ToSelf();

    }
  }

Question is, what is the proper way to start WinForms application in case the view is injected to the presenter?

Using Ninject 3.3.4 as IoC container.

1

1 Answers

1
votes

If view is initialized on the program.cs, then also presenter creates its own view?

This is because of the object scoping. If you request an IMainForm in Program.cs, and then request a Presenter, then Ninject will inject a new instance of View.MainForm for the Presenter and thus you have two instances of the view. To use the same instance you need to scope the binding in singleton scope.

Bind<IMainForm>().To<View.MainForm>().InSingletonScope();

When requesting an instance of the view, ensure you do so via your binding, i.e. var view = kernel.Get<View.IMainForm>(); otherwise Ninject will try to self-bind and will be dodging your singleton scope.