Ninject inject add an element to collection when I create the collection

199 views
Skip to first unread message

Magnus Österlund

unread,
Oct 21, 2010, 8:33:20 AM10/21/10
to ninject
I have set up the binding as following:

class TestModule:NinjectModule
{
public override void Load()
{
Bind<ICollection<Element>>().To<Collection<Element>>();
Bind<Element>().ToSelf();
}
}

When I try to get a ICollection I get a collection with ONE element. I
expect an empty collection.

var _kernel = new StandardKernel(new TestModule());

var col = _kernel.Get<ICollection<Element>>();
Console.WriteLine("Count={0}", col.Count); //Write "Count=1",
Expect "Count=0"

Tom Rathbone

unread,
Oct 21, 2010, 9:06:03 AM10/21/10
to nin...@googlegroups.com
As far as I'm aware this is the intended behaviour.  If you need an empty collection you can just use 'new' to create one,  there's usually no need for it to be injected.


2010/10/21 Magnus Österlund <magnuso...@gmail.com>

--
You received this message because you are subscribed to the Google Groups "ninject" group.
To post to this group, send email to nin...@googlegroups.com.
To unsubscribe from this group, send email to ninject+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/ninject?hl=en.


Scott Hyndman

unread,
Oct 21, 2010, 9:07:26 AM10/21/10
to nin...@googlegroups.com
Why is this expected? What is the one element?

Ian Davis

unread,
Oct 21, 2010, 9:09:28 AM10/21/10
to nin...@googlegroups.com
Tom is correct. When a collection is injected, it will find all bindings that match the generic parameter and add them to the collection being injected. If you remove your binding on Element, an empty collection would be injected.

-Ian

Tom Rathbone

unread,
Oct 21, 2010, 9:15:50 AM10/21/10
to nin...@googlegroups.com
The contents will be a newly constructed Element as Element is bound in transient scope.

The purpose of this is so that you can define multiple providers for a single service type and then pull them all back.

For example if I had an interface..

interface IConverter
{
   bool CanConvert(Type typeA, Type typeB);
   object  Convert(object a, object b);
}

I could bind..

Bind<IConverter>().To<IntToStringConverter>();
Bind<IConverter>().To<EnergyToMassConverter>();
Bind<IConverter>().To<DogToCatConverter>();

Then in my code I can find all the register converters and find the one I want to use.

kernel.Get<Collection<IConverter>>().First(c => c.CanConvert(objectA.GetType(), typeof(String)));

In other use cases you might chose to use all of the returned services or go down them in order until you find one that works.  It can be an extremely useful feature.

Hope that helps.
Reply all
Reply to author
Forward
0 new messages