how to get dependencies injected in constructors in Windows Forms
Asked Answered
H

2

10

in asp.net-mvc I have the Windsor Controller Factory that injects all the dependencies into the controllers, but how do you get this in Windows Forms ?

for example if have this Form1, how am I going to get an instance of Form1, should I use resolve (which is called ServiceLocator and anti-pattern by some ppl)?

public class Form1
{
   private IBarService _barService;

   public Form1(IBarService barService)
   {
       _barService = barService;
   }
}
Homicidal answered 5/2, 2010 at 19:50 Comment(0)
T
6

Yes, in program.cs you should make windsor resolve Form1. For the sake of being able to view the form in the designer you add an empty constructor and decorate it with the Obsolete attribute.

Tonsil answered 5/2, 2010 at 19:57 Comment(1)
The Obsolete approach is not working, designer still shows brokenYearbook
A
7

Using Constructor Injection for Forms (or other Views in other UI frameworks) is often problematic because the Visual Studio designer expects and assumes a default constructor.

In any case, a Form or other visual Control really ought to be a dumb View without behavior. It's purpose is to display whatever data you bind to it. Using the data binding features often helps in constraining you into this passive form of display.

This means that you need some sort of Controller which can instantiate the View (Form) and bind the data source to it.

This is a lot easier to do with a technology such as WPF, but it's also possible with Windows Forms. For inspiration on how to do this with Windows Forms, I suggest that you take a look at the (now retired) Composite Application Block - it's overly complicated, but it should give you some ideas on how to implement something similar yourself.

Acidophil answered 5/2, 2010 at 20:1 Comment(6)
For VS designer compatibility, you can provide a private default constructor, and make your public constructor call the default one.Cuthbertson
@Mark, I did some work with CAB a number of years ago - didn't hear that it was retired. Where did you find that it was retired?Upholsterer
@Eren Aygunes: Good point - I didn't know that. However, it doesn't really change my answer because from a design perspective, passive Views better fit the concept of a Control.Acidophil
@mreith: Perhaps 'retired' is a bad choice of words, but remember that CAB was never a product. It's not being updated or evolved, mainly because Windows Forms as a technology isn't seeing much more evolution itself.Acidophil
but what if you need dependencies in your UI? not heavy things, but things that are handy to swap out with test versions, such as a "message box provider" or "date provider"? if a control is supposed to default to a particular date value (today, this year), shouldn't I be injecting those dates somehow? the controls can be "dumb" relative to the DB, but I don't see how they can be completely "dumb", there has to be UI code. (maybe you'd say "bind the default date" but what if it's not a part of the model, only a part of the UI (ie: a filter)).Deaver
simplest example is a DateBox (my own custom control) that defaults to today. how do I get it to default to today without using DateTime.Today and without injecting an IDateProvider? (my answer so far is to use a ServiceLocator for the designer code (in my case a script (external DSL)). script code is already late-bound so a late-bound ServiceLocator should theoretically be ok).Deaver
T
6

Yes, in program.cs you should make windsor resolve Form1. For the sake of being able to view the form in the designer you add an empty constructor and decorate it with the Obsolete attribute.

Tonsil answered 5/2, 2010 at 19:57 Comment(1)
The Obsolete approach is not working, designer still shows brokenYearbook

© 2022 - 2024 — McMap. All rights reserved.