0

I want to bind IDicitionary<> to Dictionary<>. I tried the following binding:

Bind(typeof (IDictionary<,>)).To(typeof (Dictionary<,>));

Ninject sees the copy constructor, and tries to use it - which leads to a cyclic dependency.

How do I correctly specify this binding?

Wilbert
  • 7,251
  • 6
  • 51
  • 91
  • What is it you are trying to achieve here? What's the use for you to inject an empty dictionary into consumers? Do note that a `Dictionary` is not a service, it's just a data object. A DI container is built for composing object graphs that consist of services (that contain behavior); not data objects. – Steven Feb 21 '14 at 12:25
  • It helps unit testing. In production, I want it to start with an empty container (which could be allocated with new, sure, but it doesn't matter). For tests however, it might make sense to pass a pre-populated one so I can test specific things without having to setup. – Wilbert Feb 21 '14 at 13:39
  • But with what data do you want to fill it during testing? – Steven Feb 21 '14 at 13:53
  • Whatever is appropriate for the test. I might also pass in a mocked dict. – Wilbert Feb 21 '14 at 15:13
  • It seems to me that you are trying to do is a smell. The dictionary is much to generic and makes your application completely dynamic (just as if you're doing late binding). If you show a concrete case for when and how you want to use this dictionary, we can show you a better alternative. – Steven Feb 21 '14 at 16:19

1 Answers1

3

One workaround and two solutions i can think of (pick the one which suits you best):

  • Create your own Dictionary MyDictionary<,> : Dictionary<,> (with only a single parameterless ctor) and Bind(typeof (IDictionary<,>)).To(typeof (MyDictionary<,>));

  • Adapt the binding to: this.Bind(typeof(IDictionary<,>)).ToMethod(ctx => Activator.CreateInstance(typeof(Dictionary<,>).MakeGenericType(ctx.GenericArguments)));

  • Adapt the binding to this.Bind(typeof(IDictionary<,>)).ToConstructor(ctx => Activator.CreateInstance(typeof(Dictionary<,>).MakeGenericType(ctx.Context.GenericArguments)));

For the difference between .ToMethod()and .ToConstructor() see: What's the difference between .ToConstructor and .ToMethod in Ninject 3?

Community
  • 1
  • 1
BatteryBackupUnit
  • 12,934
  • 1
  • 42
  • 68
  • But I don't want my own dict, I want the .Net IDictionary<>. – Wilbert Feb 21 '14 at 13:40
  • These are three separate solutions / workarounds. Pick the one most to your liking. (Sorry for not specifying this clearly) – BatteryBackupUnit Feb 21 '14 at 14:10
  • btw., since i suggested inheriting from the `Dictionary` class - not the `IDictionary` interface - one could argue how much this would be your own implementation - you would not even need to write one additional line except for the class definition. But i would agree that it is still smelly. – BatteryBackupUnit Feb 21 '14 at 14:13