Ninject + Windows Forms

1,549 views
Skip to first unread message

Erik

unread,
Mar 27, 2009, 6:02:18 PM3/27/09
to ninject
I'm starting a new project that will include a WIndows forms component
(as well as a windows service component). This is basically a Smart
Client sort of application that connects to the service and data is
sent back and forth.

I've never used a DI or IoC framework before, and i've looked at a
bunch. Ninject seems to be the best fit with what i want (don't want
XML configuration and something fairly simple and straight forward).

I'm scratching my head a little, though, about how best to apply
Ninject to a Windows forms application. Should I create my forms with
Ninject? Since Windows Forms don't have an "IForm" interface or
anything like that, it means either designing my own interface or
using self-binding.

Further, I'm trying to decide how i'm supposed to use the Kernel
deeper in the application. Do I create a new instance in every
object, or do I pass a pointer to the kernel around to everything?
The latter seems to defeat the purpose, and using a Singleton pattern
to return the kernel also seems to defeat the purpose.

I can see, perhaps a factory of some kind, but isn't that what the
kernel itself ultimately is? So why do i need to create a factory to
return another (essentially) factory? Yes, i know an IoC container is
much more than a factory, but I mean it serves the same function at
that level.

I've read a number of posts on where to put your container for other
frameworks, and the solutions all see way more complicated than they
should have to be.

Most of the Ninject samples i've seen have been web based or too
simplistic. Nothing for a real application.

Can anyone help me get started on the right path here?

Dave

unread,
Mar 28, 2009, 7:02:25 AM3/28/09
to ninject


On Mar 27, 11:02 pm, Erik <eri...@gmail.com> wrote:
> I'm starting a new project that will include a WIndows forms component
> (as well as a windows service component).  This is basically a Smart
> Client sort of application that connects to the service and data is
> sent back and forth.
>
> I've never used a DI or IoC framework before, and i've looked at a
> bunch.  Ninject seems to be the best fit with what i want (don't want
> XML configuration and something fairly simple and straight forward).
>
> I'm scratching my head a little, though, about how best to apply
> Ninject to a Windows forms application.  Should I create my forms with
> Ninject?  Since Windows Forms don't have an "IForm" interface or
> anything like that, it means either designing my own interface or
> using self-binding.
Beside that you can create a instance of every form (or (user)control)
with just kernet.Get<FormType>();
However most Windows application implement the MVP (Model View
Presenter) pattern or a variant like MVVM (Model View ViewModel).

You probably heart about the new asp.net MVC framework. Where MVC
frameworks work with controllers, MVP application work with
Presenters.
The presenter implements the logic and acts as an intermediary between
you business objects and the view (your form or control).

So before you start writing something of your own, you'd might want to
search for already existing MVP frameworks for .NET.
Personally I like Caliburn (A WPF MVP framework).

Writing a Ninject adapter for Caliburn isn't that hard and you only
need it temporary until Ninject2 is officially released.


> Further, I'm trying to decide how i'm supposed to use the Kernel
> deeper in the application.  Do I create a new instance in every
> object, or do I pass a pointer to the kernel around to everything?
> The latter seems to defeat the purpose, and using a Singleton pattern
> to return the kernel also seems to defeat the purpose.
Most application create a KernelContainer object which has a static
property Kernel which returns an IKernel instance. When the container
haven't created a kernel instance yet, it usually call a (private)
CreateKernel method.
After that you can access Ninject from throughout your application by
using KernelContainer.Kernel.



> I can see, perhaps a factory of some kind, but isn't that what the
> kernel itself ultimately is?  So why do i need to create a factory to
> return another (essentially) factory?  Yes, i know an IoC container is
> much more than a factory, but I mean it serves the same function at
> that level.
IoC is a very simple concept. Instead of the framework dictating what
libraries your have to, the control is shifted to the application.
It's the application that says I want NLog as a logger and not
log4net. To Achieve that you need DI (Dependency Injection). Unlike
Martin Fowler says, DI is a mean to get IoC. DI != IoC.
For IoC to work the underlying framework needs to only work with
interfaces and adapters (which of course implement a interface).


> I've read a number of posts on where to put your container for other
> frameworks, and the solutions all see way more complicated than they
> should have to be.
> Can anyone help me get started on the right path here?
If you don't find a framework that suits your needs, at least take a
look how other framework have solve their problems.


Hope this helps,
Dave

Erik

unread,
Mar 29, 2009, 6:27:33 PM3/29/09
to ninject
On Mar 28, 7:02 am, Dave <zypre...@gmail.com> wrote:
> Beside that you can create a instance of every form (or (user)control)
> with just kernet.Get<FormType>();

Yes, I have done that using SelfBinding and it works ok, but it seems
like i'm still creating a dependancy there. I mean, is there
substantially any difference between:

Form1 form1 = new Form1()

and

Form1 form1 = kernel.Get<Form1>()

Although I could see a little gain from

Form form = kernel.Get<Form1>()

> However most Windows application implement the MVP (Model View
> Presenter) pattern or a variant  like MVVM (Model View ViewModel).

I haven't yet chosen a model yet.. i'm just playing around with the
IoC framework right now.

> Most application create a KernelContainer object which has a static
> property Kernel which returns an IKernel instance. When the container
> haven't created a kernel instance yet, it usually call a (private)
> CreateKernel method.
> After that you can access Ninject from throughout your application by
> using KernelContainer.Kernel.

You mean a singleton, essentially. I thought Singletons were bad.

> For IoC to work the underlying framework needs to only work with
> interfaces and adapters (which of course implement a interface).

Well, I don't think you need strictly interfaces, since abstract
classes work almost as well... but yes.

> > I've read a number of posts on where to put your container for other
> > frameworks, and the solutions all see way more complicated than they
> > should have to be.
> > Can anyone help me get started on the right path here?
>
> If you don't find a framework that suits your needs, at least take a
> look how other framework have solve their problems.

Well, like I said.. the solutions i've seen have largely been targeted
at web based systems. They typically use the HttpContext to store the
container, which is not applicable to a windows forms app.

Arash Emami

unread,
Mar 29, 2009, 10:52:32 PM3/29/09
to nin...@googlegroups.com
Hi Erik.

In your example, if you know for for certain that Form1 will never
have any dependencies, then yes the following are equivalent:


> Form1 form1 = new Form1()
>
> and
>
> Form1 form1 = kernel.Get<Form1>()


And if that were the case there would be no reason to use Ninject or
any other DI framework.

The reason to use a DI framework is because the following 2 statements
are also equivalent:

Form1 form1 = new Form1(dependency1, dependency2, dependency3, etc.)

and

Form1 form1 = kernel.Get<Form1>()


That's all a DI framework is there for - to take care of the
dependencies for you.


And singletons are fine for when you want a singleton :)

Erik

unread,
Mar 30, 2009, 2:00:48 AM3/30/09
to ninject
On Mar 29, 10:52 pm, Arash Emami <aemam...@gmail.com> wrote:
> The reason to use a DI framework is because the following 2 statements
> are also equivalent:
>
> Form1 form1 = new Form1(dependency1, dependency2, dependency3, etc.)
>
> and
>
> Form1 form1 = kernel.Get<Form1>()

This is a good point. Even though you are still creating a dependancy
on Form1, you're removing dependancies on the rest.

> And singletons are fine for when you want a singleton :)

My understanding is that singletons are bad because they make testing
difficult. So i'm confused why you would say that.

Dave

unread,
Mar 30, 2009, 7:41:59 AM3/30/09
to ninject


On Mar 30, 12:27 am, Erik <eri...@gmail.com> wrote:
> On Mar 28, 7:02 am, Dave <zypre...@gmail.com> wrote:
>
> > Beside that you can create a instance of every form (or (user)control)
> > with just kernet.Get<FormType>();
>
> Yes, I have done that using SelfBinding and it works ok, but it seems
> like i'm still creating a dependancy there.  I mean, is there
> substantially any difference between:
>
> Form1 form1 = new Form1()
>
> and
>
> Form1 form1 = kernel.Get<Form1>()
>
> Although I could see a little gain from
>
> Form form = kernel.Get<Form1>()

Well, using Ninject to create a instance also injects a depended
objects to your constructor, methods and properties (if marked with
Inject attribute).
It's a bit like you have a dynamic Bind<Form1>().ToSelf() binding. If
you create the instance yourself you still have to call Kernel.Inject
() to make sure all you depended objects are set.



> > Most application create a KernelContainer object which has a static
> > property Kernel which returns an IKernel instance. When the container
> > haven't created a kernel instance yet, it usually call a (private)
> > CreateKernel method.
> > After that you can access Ninject from throughout your application by
> > using KernelContainer.Kernel.
>
> You mean a singleton, essentially.  I thought Singletons were bad.
static classes are 'bad', because the compiler inserts all kinds of
locking statement to prevent multiple processes to call the class for
the first time.
A normal container with only one static method (like Kernel) does not
have this performance penalty.


> > For IoC to work the underlying framework needs to only work with
> > interfaces and adapters (which of course implement a interface).
>
> Well, I don't think you need strictly interfaces, since abstract
> classes work almost as well... but yes.
Abstract class should implement partially a interface. An abstract is
a partial concrete implementation or at least a start of it. If a
abstract class doesn't use virtual or abstract accessors you can't
change that behavior and that contradicts with inverting the control.
Ninject is a very good example of this. Everything is interface based.
But to give end-users a head start, also abstract and concrete
implementations are provided. However you can choose to totally ignore
Nates approach and develop you own. With IoC you - the developer - in
charge, not the developer of the framework.

And how much trouble is it to right click on you abstract class and
choose 'Extract interface'? If you have a tool like Refactor you have
even more control how to extract the interface.



> > > I've read a number of posts on where to put your container for other
> > > frameworks, and the solutions all see way more complicated than they
> > > should have to be.
> > > Can anyone help me get started on the right path here?
>
> > If you don't find a framework that suits your needs, at least take a
> > look how other framework have solve their problems.
>
> Well, like I said.. the solutions i've seen have largely been targeted
> at web based systems.  They typically use the HttpContext to store the
> container, which is not applicable to a windows forms app.
A windows forms app has a Program class. Iirc Ninject (1) has even a
basic implementation of the MVP pattern in it's Integration namespace.
Have you looked at the Smart Client Software Factory at codeplex? This
framework is totally devoted to (Classic) Windows applications.
You can also search you 'Composite UI forms'.

Using the HttpContext as a container for the kernel isn't that
different from a KernelContainer. Both return a instance of the
IKernel interface and how they implement and store that instance is
basically not so relevant.


Hope this helps,
Dave

Dave

unread,
Mar 30, 2009, 7:59:44 AM3/30/09
to ninject
Why does this make testing more difficult? My KernelContainer uses a
delegate for the CreateKernel method.
With that delegate I can use another kernel for testing that with the
end application.

public delegate void CreateKernelDelegate();

public class KernelContainer
{
private static IKernel kernel;

public static CreateKernelDelegate CreateKernel;

public static IKernel Kernel
{
if (kernel == null)
{
lock(kernel)
{
if (kernel != null) return kernel; //double check lock check
(queued caller)

kernel = CreateKernel();
}
}
return kernel;
}


public class Program
{
public static void Main()
{
KernelContainer.CreateKernel =
DefaultApplicationKernel.CreateKernel; //static method
Application.Run(New Form1());
}
}

All my unittests have their own CreateKernel method which set the
bindings they need.


Like I explained in my previous post, singletons on a static marked
class have a performance penalty, but singletons are not bad.

Hope this helps,
Dave

Nate Kohari

unread,
Mar 30, 2009, 9:26:56 AM3/30/09
to nin...@googlegroups.com
Erik:

When activated by a DI framework like Ninject, Singletons don't make testing more difficult -- it's only when you define them via the "Singleton pattern" in the language that it becomes difficult to test them.

Feel free to use singletons powered by Ninject with impunity. :)


-Nate

Erik

unread,
Mar 30, 2009, 11:46:39 PM3/30/09
to ninject
Yes, Nate. That's precisely my point. Dave suggested using the
singleton pattern to access the kernel instance.

I said I thought this was bad.
> > Dave- Hide quoted text -
>
> - Show quoted text -

Dave

unread,
Mar 31, 2009, 5:48:02 AM3/31/09
to ninject


On Mar 31, 5:46 am, Erik <eri...@gmail.com> wrote:
> Yes, Nate.  That's precisely my point.  Dave suggested using the
> singleton pattern to access the kernel instance.
>
> I said I thought this was bad.
Ninject2 introduces even a IHaveKernel interface so it's easier to
discover whether a HttpApplication has contains a kernel property (a
singleton). Have you looked at the MVC implementation? Implemented
using a KernelContainer with a static kernel property (singleton).
The Ninject 2 implementation uses a singleton property on the
NinjectHttpApplication.

Let me put it in a different way. Without a singleton, how do you get
everytime the same instance of the Ninject kernel (believe me, you
don't want multiple kernel instances in one appliaction unless you
*REALLY* know how to isolate them). Probably without knowing you use
singletons al the time. Ever used Configuration(Manager).AppSettings,
HttpContext.Current or Thread.Current? Even worse, the Application
class (both WinForms as WPF) is one singleton facade. How else can you
*just* do Application.DoEvents()??

Singletons provide you with a single source for an object. If the
class handles the singleton pattern itself (ie not marking the class
itself static, but only a few methods/properties) like my
KernelContainer and you provide a way to customize the creation of the
singleton, singletons don't have to be a negative thing wih unit
testing. It makes it even easier, because both in my application as
the unittests I use the KernelContainer.

To make things absolutely clear: I only use a singleton for the kernel
instance. All other singletons are handled by an IoC framework.

Padcom

unread,
Mar 31, 2009, 3:35:18 PM3/31/09
to ninject
Dave:

> everytime the same instance of the Ninject kernel (believe me, you
> don't want multiple kernel instances in one appliaction unless you
> *REALLY* know how to isolate them). Probably without knowing you use

I'm confused: StandardKernel is the class that encapsulates the
container. Does that mean that you might run into trouble by having 2
instances of that class?

> singletons al the time. Ever used Configuration(Manager).AppSettings,
> HttpContext.Current or Thread.Current? Even worse, the Application
> class (both WinForms as WPF) is one singleton facade. How else can you

Am I missing something? Are the Http.Contenxt and Thread.Current real
singletons? If so what's separating different clients connected at
once using 2 distinct threads?

Matthias.

Padcom

unread,
Mar 31, 2009, 3:53:02 PM3/31/09
to ninject
Erik:

Singletons implemented as a pattern (MyClass.Instance property with
private constructor) are bad. And then it only gets bad and worse when
you use them and do unit tests. Make no mistake about it. However what
the suggestion might be for a WinForms application is that you
essentially create the kernel in your Main method and get the form out
of it.

StandardKernel kernel = new StandardKernel([modules.....]);
Application.Run(kernel.Get<Form1>());

That will give you the power of singleton (there's going to be
absolutely one instance of the IoC kernel) and you'll have no
unnecessary old-fashion-way singletons laying around.

Singletons powered by Ninject is a whole different story and as Nate
already stated they are 100% safe by the fact that you always get the
same instance _injected_ so you don't access them from one shared
place (that's what is wrong with the Singleton pattern in the first
place). In fact you don't really care that they are singletons - they
are just references to instance of a class.


Best regards,
Matthias.

On Mar 30, 12:27 am, Erik <eri...@gmail.com> wrote:

Erik

unread,
Apr 1, 2009, 1:30:46 AM4/1/09
to ninject
Please, read the entire thread context before you go making comments
about this.

Padcom, I understand that singletons returned from Ninject are fine.
This is not what's under discussion. If you had read the entire
thread, you would see that.

We're talking about the mechanism used to access a common Ninject
Kernel throughout the application (not just for the main form).

And yes, I know that singleton patterns are considered bad, which is
why I questioned Dave's suggestion to use of a GoF singleton pattern
to access the kernel instance.

Your answer makes it seems like multiple calls to "new StandardKernel
(...)" will return the same instance of the kernel. I don't think
that's true. Thus, how, without using a singleton pattern as Dave
suggests, should you access your kernel instance.

I'm sorry if this sounds snotty, but I'm a bit frustrated that several
people have already jumped to the wrong conclusions here because they
did not understand the context of the discussion. They just saw the
words "singleton" and "bad" and started pontificating about how IoC
solves that problem.

Great, I know it does, but IoC can't solve the problem without first
getting access to a common IoC container. It's a chicken and egg
scenario. I'm trying to figure out how to actually do that from
various parts of the application where new instances (or shared
instances) are aquired (or activated, i think the term is).
> > container, which is not applicable to a windows forms app.- Hide quoted text -

Michael Hart

unread,
Apr 1, 2009, 1:51:56 AM4/1/09
to nin...@googlegroups.com
Hi Erik,

Typically, I try to create the kernel at app initialisation and then
ensure that all of my dependencies are propagated down to any objects
created post initialisation via constructor injection and factories.
With this method there's usually no need to have access to a static
service locator, which I think most people are referring to in this
thread. The only time things get tricky is when object creation is out
of your control, in which case you may need to resort to manual
injection - I haven't looked into whether Ninject2 has any specific
Winforms support for this though, so you may need to roll your own.

Cheers,

Michael

Dave

unread,
Apr 1, 2009, 5:36:43 AM4/1/09
to ninject
On Mar 31, 9:35 pm, Padcom <pad...@gmail.com> wrote:
> Dave:
>
> > everytime the same instance of the Ninject kernel (believe me, you
> > don't want multiple kernel instances in one appliaction unless you
> > *REALLY* know how to isolate them). Probably without knowing you use
>
> I'm confused: StandardKernel is the class that encapsulates the
> container. Does that mean that you might run into trouble by having 2
> instances of that class?
It's the other way around. KernelContainer is often hiding the call to
StandardContainer. It's the singleton property that sees that it
doesn't have a instance of the kernel and needs to create one.
I have made the CreateKernel call a delegate so I can change how the
kernel is created (see one of my previous posts in this threads). It's
the delegate that determines how and with binding the kernel is
initialized, not the container.


> > singletons al the time. Ever used Configuration(Manager).AppSettings,
> > HttpContext.Current or Thread.Current? Even worse, the Application
> > class (both WinForms as WPF) is one singleton facade. How else can you
>
> Am I missing something? Are the Http.Contenxt and Thread.Current real
> singletons? If so what's separating different clients connected at
> once using 2 distinct threads?
Thread.Current exists during the lifetime of the thread and can
therefor be called a singleton.
Ninject singletons only life as long the kernel self lives. If your
destroy the kernel instance and create a new one, the first call to a
service declared as singleton would create a new instance.
It's all about scoping. A singleton is a pattern that ensures that a
class has only one instance during a certain scope. Martin Fowler has
introduced a misconception that a singleton needs to be global, just
like IoC is all about DI.

If I create two AppDomain instances in my application than I can
create easily three (isolated) singleton instances of a class. Most
'global' singletons are bound to their AppDomain instance.
But how about a web farm? Our sessions are machine independed. Binding
the singleton to a HttpApplication means that every webserver in the
webfarm has it's own instance. But in a webform HttpApplication is not
the global scope.
Using DCOM (EnterpriseServices) we are sharing singleton instances
over multiple servers as same locks really needs to be global.
Singleton services in WCF exists as long the service host lives. Again
singletons are always bound to a certain scope.

Singletons are not bad, but they are often implemented in a bad way
and because of that unit testing is harder. But the KernelContainer
makes it even easier for me to test components. Every line of my code
knows where to find the kernel instance. That prevents that every
class that needs to create other classes have to keep a reference to
the kernel. The KernelContainer sniplet is part of a adapter for a
IocContainer used by a IocFactory framework. Because my frameworks
needs to be DI Independed I cannot hold references a certain IoC/DI
instance. Since I discovered Ninject, it's been my preferred IoC
framework, but I always try to use a IoC/DI framework the client
already knows. That makes it easier for the client to accept our
software and extend it.

I hope that I was able to make argument more clear.

Regards,
Dave

Padcom

unread,
Apr 1, 2009, 5:37:32 PM4/1/09
to ninject
Erik:

> Great, I know it does, but IoC can't solve the problem without first
> getting access to a common IoC container. It's a chicken and egg
> scenario. I'm trying to figure out how to actually do that from
> various parts of the application where new instances (or shared
> instances) are aquired (or activated, i think the term is).

Look at it from this point of view: the one and only instance of your
kernel (and I'm referring here to the StandardKernel implementation
instance) exists in your Main method. It's not global, it's not a
singleton, it is just an instance of a local variable that just
happens to live as long as the entire application. In this case
there's no such thing as the chicken and egg problem because you have
literally specified what comes first (the kernel of course).

However I understand that there might be an issue of creation of other
instances on demand. To solve this problem you'd probably go either by
creating the singleton as Dave suggested or (what is in my opinion a
better solution) you'd inject the instance of your kernel into the
object that makes use of it. That way you can always use the service
locator pattern to get an instance of an object that has not been
already injected (or if you need like a dozen of them that would also
be possible). In this case the injected kernel serves more as a form
of factory for all kinds of objects and less as dependency injector
(actually both at the same time but you get the idea).

Padcom

unread,
Apr 1, 2009, 5:41:21 PM4/1/09
to ninject
Dave:

> It's the other way around. KernelContainer is often hiding the call to
> StandardContainer. It's the singleton property that sees that it
> doesn't have a instance of the kernel and needs to create one.
> I have made the CreateKernel call a delegate so I can change how the
> kernel is created (see one of my previous posts in this threads). It's
> the delegate that determines how and with binding the kernel is
> initialized, not the container.

About that: in the case that you do have the KernelContainer (which I
would never recommend - but that's me) the problem with having 2
separate kernels really exists. Bear in mind that it only exists
because of the usage of your singleton pattern to get the container in
the first place.

What I'd do (as I've stated in my previous post) is I'd inject the
instance of the kernel wherever I make use of it instead of accessing
it from one single location. That way it doesn't really matter if you
have 1, 2 or 10 kernels.

Does that makes sense?

Padcom

unread,
Apr 1, 2009, 6:22:51 PM4/1/09
to ninject
Dave:

> > Singletons are not bad, but they are often implemented in a bad way
> > and because of that unit testing is harder. But the KernelContainer
> > makes it even easier for me to test components. Every line of my code
> > knows where to find the kernel instance. That prevents that every
> > class that needs to create other classes have to keep a reference to
> > the kernel. The KernelContainer sniplet is part of a adapter for a
> > IocContainer used by a IocFactory framework. Because my frameworks
> > needs to be DI Independed I cannot hold references a certain IoC/DI
> > instance. Since I discovered Ninject, it's been my preferred IoC
> > framework, but I always try to use a IoC/DI framework the client
> > already knows. That makes it easier for the client to accept our
> > software and extend it.

I'm sorry but I really disagree with you on that one. You're saying
that you want your application to be independent of the DI framework
and that's where your KernelContainer comes in, right? to give you the
option to switch implementations as you need it. That's all nice and
clear up to the point where you use the IKernel interface fom Ninject
effectively coupling this particular framework to the rest of your
system.

I'd understand the idea of having something like a facade over the DI
that is _really_ independent. What you wrote is completly Ninject-
dependent in the sense that IKernel definition comes from the Ninject
library. So even though you've implemented it on your own using some
other container there's really not much of a difference to the rest of
the system that still needs a reference to the Ninject library.

Of course I might have misunderstand the meaning of IKernel in your
post and it might be that you intended it to be a custom interface
instead but without it being declared in the code snipped you provided
it's pointing at the definition in Ninject.Core.

Arash Emami

unread,
Apr 1, 2009, 8:33:55 PM4/1/09
to nin...@googlegroups.com
Use the Common Service Locator from http://www.codeplex.com/CommonServiceLocator

There, done.

Dave

unread,
Apr 2, 2009, 4:34:44 AM4/2/09
to ninject
On Apr 1, 11:41 pm, Padcom <pad...@gmail.com> wrote:
> Dave:
>
> > It's the other way around. KernelContainer is often hiding the call to
> > StandardContainer. It's the singleton property that sees that it
> > doesn't have a instance of the kernel and needs to create one.
> > I have made the CreateKernel call a delegate so I can change how the
> > kernel is created (see one of my previous posts in this threads). It's
> > the delegate that determines how and with binding the kernel is
> > initialized, not the container.
>
> About that: in the case that you do have the KernelContainer (which I
> would never recommend - but that's me) the problem with having 2
> separate kernels really exists. Bear in mind that it only exists
> because of the usage of your singleton pattern to get the container in
> the first place.
>
> What I'd do (as I've stated in my previous post) is I'd inject the
> instance of the kernel wherever I make use of it instead of accessing
> it from one single location. That way it doesn't really matter if you
> have 1, 2 or 10 kernels.
>
> Does that makes sense?
Well, I understand that you might inject the Ninject kernel in the a
object you create in Main. The downside of that appoach is that every
object that might have to create new object needs it's own reference.
So all those classes have either a constructor with a IKernel argument
or you end up with a IKernel property. As point out in my previous
posts, I don't only use Ninject, but the same classes also need to
work with Spring.Net, StructureMap, AutoFac, Windsor Containers,
Unity and ObjectBuilder. To achieve that we have created a IoC
abstraction layer and Ninject is just an implementation of an IoC
container. As this newsgroup is all about Ninject I try to stay with
Ninject. However our classes use the IocFactory.Get<>() method to get
a instance of an object and the IocFactory uses the Ninject container
adapter.

Some backgound information:
Our financial system is currently using Ninject (1) in a production
environment and if the singleton would create two kernels, well than I
have a serious problems because than security would be comprimised. As
our systems is ranked with 5 (out of 5) stars with the AFM (Dutch SEC)
I can promise that singletons are really singletons in their scope. On
a daily bases more than 500 intermediaries use our software to handle
financial, insurance and stock requests and after sales. We have 24
frondend servers and with the use of DCOM sessions are shared across
those 24 servers. As each requests (WCF services) require a login
token, sequenceid and checksum (next to a X.509 client certificate)
speed of the session manager is important. With 24 webservers your
don't want to requery the database (you need to verify if login token
is still valid) with every request. All active sessions live in memory
on the session server.

But I must also admit that I don't have the need for multiple
instances of the Ninject kernel. The statement was that singletons
were bad because they would me unit testing harder.
Both the container approach as object injection are good methods to
work with IoC containers. Depending on your needs you choose the one
that fits the best (or you like the most).

With regards,
Dave

Dave

unread,
Apr 2, 2009, 4:51:17 AM4/2/09
to ninject
If have tried to keep the discussion focussed on Ninject. That I use
also other IoC frameworks is unrelevant to the discussion whether
singletons are good or bad.
So I've used I native kernel container example where the CreateKernel
method is a delegate so you can vary on how the kernel is created.

In my applications I don't use IKernel of KernelContainer. We have an
IoC abstraction factory IocFactory which acts as an facade to the
application.
In a real world application I would have a like like:
DbProviderFactory dbFactory = IocFactory.Get<DbProviderFactory>
(true);
IDbConnection conn = dbFactory.CreatConnection();
conn.ConnectionString = IocFactory.Get<ConnectionStringManager>
(true).Get("Maex");

As the above is of no value to the discussion, I changed the
NinjectKernelContainer class a little bit so that it so it can
possibly be used by other who only use Ninject.
Because our applications are DI independed I pretty much have to use a
singleton pattern (the IocFactory). I apoligize for any confusion my
post might have created.

With regards,
Dave

Michael Hart

unread,
Apr 2, 2009, 6:55:25 AM4/2/09
to nin...@googlegroups.com
Hi Dave,

It sounds like you're using your DI container as a Service Locator,
but not really using dependency injection. Is it necessary to have
your IocFactory all over the place? Can you not just have your
factories, connection strings, etc injected where they need to be
(preferably in your constructors)? The more you can do that, the less
coupling you'll have.

Cheers,

Michael

Matthias Hryniszak

unread,
Apr 2, 2009, 6:57:34 AM4/2/09
to nin...@googlegroups.com
Michael:

I was just about to say the same thing - no DI, just SL..

Dave

unread,
Apr 2, 2009, 1:41:26 PM4/2/09
to ninject
On Apr 2, 12:55 pm, Michael Hart <michael.hart...@gmail.com> wrote:
> Hi Dave,
>
> It sounds like you're using your DI container as a Service Locator,  
> but not really using dependency injection. Is it necessary to have  
> your IocFactory all over the place? Can you not just have your  
> factories, connection strings, etc injected where they need to be  
> (preferably in your constructors)? The more you can do that, the less  
> coupling you'll have.
Again, in my previous post I just gave an example. I also use the
IocFactory to create new instances of objects.
You might have seen the Micosoft Common Service Locator library. You
can create an instance of a class and inject a IServiceLocator
instance and that reference to create some other instances.
However if you don't use an singleton implementation almost ALL your
classes need to store the container reference and use that one to
create new instances. If you ever use Activator.CreateInstance or New X
() and don't use IKernel.Inject() you're unable to get a reference to
the container reference. It's also adds a dependency that the creator
of the object uses a container. But the IServiceLocator reference you
pass is exactly the same as you would get from ServiceLocator.Current.
The main difference in the abstraction facade is that ServiceLocator
wants an ServiceLocatorProvider instance where our IocFactory uses a
delegate to create a instance. As IServiceLocator and
ServiceLocator.Current both refer to the same instance, why bother to
pass the IServiceLocator? Not really a argument these days were memory
is almost free, but every time you pass IServiceLocator to a class and
not have used it, you've wasted 4 bytes on the stack.

Most developers don't really have a need for IoC abstraction, but as
we only provide (base) services to intermediaries we need be able to
change the container implementation. If you don't use an service
locator abstraction layer, you actually add coupling as Ninject is
required to run the application. This is a contradiction to the IoC
pattern where the end user (not you) decides what libraries are used.
Because I'm a singleton and my object is created by a third party
(like SAP, Microsoft Dynamics, etc) I can still use IocFactory.Load
(this); to inject all the dependencies the object needs.

As I wrote earlier there isn't just a best approach, but are several.
Use the methodology you like or need.

Regards,
Dave

Michael Hart

unread,
Apr 2, 2009, 6:15:17 PM4/2/09
to nin...@googlegroups.com
My point was that you seem to be overusing the Service Locator pattern
- not actually declaring your dependencies at all.

So, instead of this (from your example):

// this method hides its dependencies
void SomeMethod()
{
var dbFactory = IocFactory.Get<DbProviderFactory>(true);
var conn = dbFactory.CreateConnection();
conn.ConnectionString = IocFactory
.Get<ConnectionStringManager>(true).Get("Maex");

// Do other things
}

Either do this:

void SomeMethod(IDbConnection conn)
{
// use conn...
}

Or this:

void SomeMethod(DbProviderFactory dbFactory, ConnectionStringManager
connManager)
{
var conn = dbFactory.CreateConnection();
conn.ConnectionString = connManager.Get("Maex");
// etc
}

Or this (constructor injection):

class SomeObject
{
readonly DbProviderFactory dbFactory;
readonly ConnectionStringManager connManager;

SomeObject(DbProviderFactory dbFactory, ConnectionStringManager
connManager)
{
this.dbFactory = dbFactory;
this.connManager = connManager;
}

void SomeMethod()
{
var conn = dbFactory.CreateConnection();
conn.ConnectionString = connManager.Get("Maex");
// etc
}
}

Or even better, use a DB factory that returns a connection given a
connection string name and get rid of the ConnectionStringManager
altogether.

My point is, instead of littering your code with static references to
some service locator - or even passing the service locator around -
just declare your dependencies explicitly. It will make your code much
easier to test and makes the intent much clearer to anyone reading it.
Then using Ninject, or whatever IoC container you choose, setup your
objects from the root so that dependencies can be passed down.

Hope that helps,

Michael

Dave

unread,
Apr 3, 2009, 3:43:07 AM4/3/09
to ninject


On Apr 3, 12:15 am, Michael Hart <michael.hart...@gmail.com> wrote:
> My point was that you seem to be overusing the Service Locator pattern  
> - not actually declaring your dependencies at all.
>
> Or even better, use a DB factory that returns a connection given a  
> connection string name and get rid of the ConnectionStringManager  
> altogether.
I use the System.Data.DbProviderFactory. And our systems must be able
to connect with any database.
So even when the DB factory was able to set the connectionstring I
wasn't able to use it.

I try to pass as little objects using the constructor. Mostly I use
property injection. And here lies a problem if you're using Unity. It
requires that you set the InjectionProperty attribute.
So I had to write all kind of object builders to inject the stuff at
both ObjectBuilder and Unity level. Unlike with Ninject you can't
change the attributes it looks for.
Lucky for me, Unity isn't widely in use with corporations. At least in
Europe (financial sector) Windsor Containers and Spring.net as the
most popular DI frameworks, but Ninject is gaining ground fast.

> My point is, instead of littering your code with static references to  
> some service locator - or even passing the service locator around -  
> just declare your dependencies explicitly. It will make your code much  
> easier to test and makes the intent much clearer to anyone reading it.  
> Then using Ninject, or whatever IoC container you choose, setup your  
> objects from the root so that dependencies can be passed down.

As I mentioned earlier, we mostly provide services. Some services
exists in classes, others are just a static methods. Our main audience
are intermediaries up to 50 employees with little or no development
experience.
Key is to hide as much as possible. The core framework is using real
dependency injection. Although we have written an implementation for
Microsoft CSL, it still requires the developer to setup the container
instance.
As Microsoft CSL is mostly a frontend facade to DI frameworks it
doesn't take care of the bindings itself. Our IocFactory does register
the bindings with the container and even has support for dependencies.
Every ServiceRegistration can specify on which dependencies it counts.
These dependencies are also used to determine the load order as a
service might have Initialization request. The Initialization method
is called the moment the binding is registered with the container.

I can't say the 'bridging' class unit tests are harder to write than
unit tests for class that follow 'proper' DI conventions. But I have
to agree that code with less service locator code is cleaner. However
if only one method is using a certain service, I will not use property
injection, but use the service locator or you end up with classes with
so much fields and properties to hold references that it becomes
harder to 'see' what properties are controlling class behavior and
which are only for infrastructure and you use more memory than needed
as the GC can only dispose the reference variables when the class
itself is disposed. When you only use a service in one method, in our
case it's better to use a service locator and store a reference in a
local variable. This variable is disposed (or at least marked for
disposal) the moment the method is finished. Some services are also
running on third party servers and no-one's waiting for resource hogs.

But I feel we drifting to much to my usage of DI framework which isn't
how most developers would use Ninject.
At the beginning of this thread (some light years ago ;-) someone made
the remark that singletons make unit testing harder and that
singletons needs to be global. I responded that that remark. But
whether you use a service locator to retrieve a service or use some
kind of injection doesn't really matter. I was trying to make that
point.


With regards,
Dave

Matthias Hryniszak

unread,
Apr 3, 2009, 4:56:56 AM4/3/09
to nin...@googlegroups.com
Dave:


> But I feel we drifting to much to my usage of DI framework which isn't
> how most developers would use Ninject.
> At the beginning of this thread (some light years ago ;-) someone made
> the remark that singletons make unit testing harder and that
> singletons needs to be global. I responded that that remark. But
> whether you use a service locator to retrieve a service or use some
> kind of injection doesn't really matter. I was trying to make that
> point.

As a matter of fact it does matter if you're using an IoC as service locator or not. Service locator means using singleton pattern which _is_ evil in the case of unit testing. IoC is all about decoupling whereas the Service Locator is all about coupling. I see that this distinction is still very blurry in your posts. Look at the difference Michael showed and compare it to what you've posted:


> IDbConnection conn = dbFactory.CreatConnection();
> conn.ConnectionString = IocFactory.Get<
> ConnectionStringManager>
> (true).Get("Maex");

That's exactly the point you're missing.

M.

2009/4/3 Dave <zypr...@gmail.com>

Erik

unread,
Apr 3, 2009, 2:09:31 PM4/3/09
to ninject
In that light, I tried something new and I'm unsure of the results at
this point.

I took my Winform object and added an IKernel parameter to the
constructor. Ninject happily injected a kernel instance into it, but
i'm unsure if this is a new instance of the kernel or a shared
instance. If it's a shared instance, then this solves my problem
(although it still makes each class dependant on ninject, but I can
live with that).

I did not create a mapping for IKernel, so I assume Ninject has a
default mapping for this. But is it a single instance?

On Apr 3, 4:56 am, Matthias Hryniszak <pad...@gmail.com> wrote:
> Dave:
>
> > But I feel we drifting to much to my usage of DI framework which isn't
> > how most developers would use Ninject.
> > At the beginning of this thread (some light years ago ;-) someone made
> > the remark that singletons make unit testing harder and that
> > singletons needs to be global. I responded that that remark. But
> > whether you use a service locator to retrieve a service or use some
> > kind of injection doesn't really matter. I was trying to make that
> > point.
>
> As a matter of fact it does matter if you're using an IoC as service locator
> or not. Service locator means using singleton pattern which _is_ evil in the
> case of unit testing. IoC is all about decoupling whereas the Service
> Locator is all about coupling. I see that this distinction is still very
> blurry in your posts. Look at the difference Michael showed and compare it
> to what you've posted:
>
> > IDbConnection conn = dbFactory.CreatConnection();
> > conn.ConnectionString = IocFactory.Get<> ConnectionStringManager>
> > (true).Get("Maex");
>
> That's exactly the point you're missing.
>
> M.
>
> 2009/4/3 Dave <zypre...@gmail.com>
> > Dave- Hide quoted text -

Erik

unread,
Apr 3, 2009, 2:12:50 PM4/3/09
to ninject
I forgot to mention, I'm using Ninject 2 beta from about a week ago..
> > - Show quoted text -- Hide quoted text -

Matthias Hryniszak

unread,
Apr 3, 2009, 2:36:07 PM4/3/09
to nin...@googlegroups.com
Erik:

    class WithContainer {
        [Inject]
        public IKernel Kernel { get; set; }
    }

    class Program {
        static void Main(string[] args) {
            IKernel kernel = new StandardKernel();
            WithContainer o1 = kernel.Get<WithContainer>();
            WithContainer o2 = kernel.Get<WithContainer>();
            o1.Kernel.Options.GenerateDebugInfo = false;
            if (o1.Kernel.Options.GenerateDebugInfo == o2.Kernel.Options.GenerateDebugInfo) {
                o1.Kernel.Options.GenerateDebugInfo = true;
                if (o1.Kernel.Options.GenerateDebugInfo == o2.Kernel.Options.GenerateDebugInfo) {
                    Console.WriteLine("Same kernel");
                } else {
                    Console.WriteLine("Different kernel");
                }
            } else {
                Console.WriteLine("Different kernel");
            }
        }
    }

This application yelds "Same kernel". Also look at the unit tests - there's a test called PropertyInjectionStrategyFixture that shows the same thing.


Best regards,
Matthias.

2009/4/3 Erik <eri...@gmail.com>

Erik

unread,
Apr 3, 2009, 6:18:25 PM4/3/09
to ninject
Thanks for the followup testing. Good to know that this works. It's
just not obvious that you can do this.
> > > - Show quoted text -- Hide quoted text -

Michael Hart

unread,
Apr 3, 2009, 7:57:05 PM4/3/09
to nin...@googlegroups.com
Hi Erik,

Can I ask why you need a reference to the kernel? Can you not pass
whatever dependencies (even if they're factories, etc) in to the
Winform constructor instead? The factories can still talk to the
kernel behind the scenes if need be - but this way you wouldn't be
dependent on the kernel in your app as such (so your dependencies
would be more explicit).

Cheers,

Michael

Ben Fulton

unread,
Apr 3, 2009, 9:28:16 AM4/3/09
to nin...@googlegroups.com
So (to bring the discussion full circle) suppose you have a WinForms app, and the main form is required to create another form or two somewhere along the way.  It seems like your choices are:
 
1) Have your main form depend directly on the kernel.  OnClick() { kernel.Get<SubForm>(); }
2) Pass in an IFormCreator to the constructor of the main form, using Ninject to bind it, and have the implementation depend on the kernel.
3) Create the subform directly, give it a dependency on the kernel, and have it use the kernel to spin up any domain-level objects it might need.
How would you do it?

Michael Hart

unread,
Apr 4, 2009, 6:02:40 PM4/4/09
to nin...@googlegroups.com
Number 2 sounds like the way to go to me - you could even have
specialisations of the form creator if you needed, ie
IFormCreator<CustomerForm> or ICustomerFormCreator : IFormCreator

Cheers,

Michael

Matthias Hryniszak

unread,
Apr 4, 2009, 6:12:35 PM4/4/09
to nin...@googlegroups.com
I'd also go with the 2nd option. The one thing that I don't really like is the fact that it is still depending on the kernel. I'll try to put something together that would work more like providers in Guice. For now the notion of providers in Ninject is more like a kernel-dependent factory and that only gets you half the way through.

Matthias.

Michael Hart

unread,
Apr 4, 2009, 9:06:14 PM4/4/09
to nin...@googlegroups.com
Matthias,

> The one thing that I don't really like is the fact that it is still
> depending on the kernel.

In what way? You mean your factory implementations would be dependent
on the kernel? I don't see any problem with that. As long as your app
just sees an IFormCreator, it shouldn't matter if this is implemented
as a NinjectFormCreator behind the scenes (or a
StructureMapFormCreator, or... etc)

Or are you referring to something else?

Cheers,

Michael

Matthias Hryniszak

unread,
Apr 4, 2009, 9:14:48 PM4/4/09
to nin...@googlegroups.com
Michael:

yes, you're right. As long as you don't expose the inner-workings of your factory you should be on the safe side.
It's a pity that Ninject doesn't support something like Provider in Guice. The definition of Provider in Ninject exposes to many dependencies to the framework itself (see method parameters, the IContext ones).

Best regards,
Matthias.
Reply all
Reply to author
Forward
0 new messages