I would make the dependency be at the form-to-form level. You want to have something in between that.
namespace Example
{
public class SettingsRepository
{
public SettingsRepository()
{
}
}
public class SettingsForm
{
private SettingsRepository _settingsRepository;
public SettingsForm( SettingsRepository settingsRepository )
{
_settingsRepository = settingsRepository;
}
}
public class MainForm
{
private SettingsRepository _settingsRepository;
private Func<SettingsForm> _createSettingsForm;
public MainForm( Func<SettingsForm> createSettingsForm, SettingsRepository settingsRepository )
{
_createSettingsForm = createSettingsForm;
_settingsRepository = settingsRepository;
}
}
}
Then you inject a Func<SettingsForm>
into your class to remove the direct usage of the container / Kernel from your code (if you're doing inline Get
calls all over the place, you're doing Service Location, which is a different thing to DI entirely).
public class ExampleNinjectModule : NinjectModule
{
public override void Load()
{
Bind<Func<SettingsForm>>().ToMethod( context => () => context.Kernel.Get<SettingsForm>() );
}
}
Another approach is to add a Kernel
to your constructor args (Ninject automatically resolves it), but that quickly becomes a mess in general.
I tried a quick search for samples, but sadly didnt find anything quickly in the WinForms space. I'd suggest perhaps looking for WPF examples instead.
Bottom line is you wont go far wrong if you:
- stick with Constructor Injection, and avoiding direct usage of Kernel or container attributes in your real code as much as possible
- Dont use a Global Kernel and/or Service Location