Inject Array of Interfaces in Ninject

Consider the following code.

public interface IFoo { } public class Bar { public Bar(IFoo[] foos) { } } public class MyModule : NinjectModule { public override void Load() { Bind<IFoo[]>().ToConstant(new IFoo[0]); // ToConstant() is just an example } } public class Program { private static void Main(string[] args) { var kernel = new StandardKernel(new MyModule()); var bar = kernel.Get<Bar>(); } }

When I try to run the program I get the following exception.

Error activating IFoo
No matching bindings are available, and the type is not self-bindable.
Activation path:
2) Injection of dependency IFoo into parameter foos of constructor of type Bar
1) Request for Bar

How can I inject / bind to an array in Ninject?

Thanks for your time.

Edit:
My application imports data which is created by a third party component. The import process applies different kind of filters (e.g. implementations of different filter interfaces). The rules for filtering change quite often but are too complex to be done with pure configuration (and a master filter).

I want to make adding/editing filters as easy as possible. What I have is an assembly where all the filter implementations are located in. I tried to bind every filter interface to the following method (which provides an instance of every implementation of that filter type). Basically I want to avoid the need to change my Ninject module when I add/remove filter classes.

private IEnumerable<TInterface> GetInterfaceImplementations<TInterface>(IContext context) { return GetType().Assembly.GetTypes() .Where(t => typeof (TInterface).IsAssignableFrom(t) && IsConcreteClass(t)) .Select(t => Kernel.Get(t)).Cast<TInterface>(); }

I am feeling a bit guilty in terms of bypassing the containers DI mechanism. Is this a bad practice? Is there a common practice to do such things?

Resolution:
I use a wrapper class as bsnote suggested.

-------------Problems Reply------------

This is largely a restatement of @bsnote's answer (which I've +1d) which may help in understanding why it works in this manner.

Ninject (and other DI / addin frameworks) have two distinct facilities:

  1. the notion of either binding to a single unambiguous implementation of a service (Get)
  2. A facility that allows one to get a set of services [that one then programmatically picks one of or aggregates across in some way] (GetAll / ResolveAll in Ninject)

Your example code happens to use syntax that's associated with 2. above. (e.g., in MEF, one typically use [ImportMany] annotations to make this clear)

I'd need to look in the samples (look at the source - its really short, clean and easy to follow) to find a workaround for this.

However, as @bsnote says, one way of refactoring your requirement is to wrap the array either in a container, or to have an object that you ask for it (i.e., a factory method or repository type construct)

It may also be useful for you to explain what your real case is - why is there a naked array ? Surely there is a collection of items construct begging to be encapsulated underlying all this - this question certainly doesnt come up much?

EDIT: There are a set of scanning examples in the extensions that I imagine would attack a lot of the stuff you're trying to do (In things like StructureMap, this sort of stuff is more integrated, which obviously has pros and cons).

Depending on whether you're trying to achieve convention over configuration or not, you might want to consider sticking a marker interface on each type of plugin. Then you can explicitly Bind each one. Alternately, for CoC, you can make the Module's Load() routine loop over the set of implementations you generate (i.e., lots of individual Gets) in your edit.

Either way, when you have the multiple registrations in place you can happily either 'request' a T[] or IEnumerable<T> and get the full set. If you want to achieve this explicitly (i.e., Service Locator and all it implies - like in you're doing, you can use GetAll to batch them so you're not doing the looping that's implicit in the way you've done it.

Not sure if you've made this connection or if I'm missing something. Either way, I hope it's taught you to stick some code into questions as it speaks > 1000 words :P

It was a problem for me as well. Ninject injects each item of an array instead of the array itself, so you should have a mapping defined for the type of array items. Actually there is no possibility to map the array as a type with the current version of Ninject. The solution is to create a wrapper around the array. Lazy class can be used for example if it suits you. Or you can create your own wrapper.

Ninject supports multi injection which would resolve your issue. https://github.com/ninject/ninject/wiki/Multi-injection

public interface IFoo { }
public class FooA : IFoo {}
public class FooB : IFoo {}

public class Bar
{
//array injected will contain [ FooA, FooB ]
public Bar(IFoo[] foos) { }
}

public class MyModule : NinjectModule
{
public override void Load()
{
Bind<IFoo>().To<FooA>();
Bind<IFoo>().To<FooB>();
//etc..
}
}

Category:c# Views:0 Time:2010-06-23

Related post

  • Castle Windsor can't inject an array of interface types 2009-06-29

    I have a class that takes an array of interfaces in the constructor: public class Foo<T1, T2> : IFoo<T1, T2> { public Foo(IBar[] bars) { ... } } My container registration looks as follows: container.Register(AllTypes.Pick().FromAssemblyNa

  • Passing an array of interfaces from C# to C++/CLI 2010-08-12

    I am trying to pass an array of interfaces from C# to C++/CLI. Here is the code: // *** SafeArrayTesting_PlusPlus.cpp *** #include "stdafx.h" #include <comdef.h> using namespace System; using namespace System::Runtime::InteropServices; namespac

  • instantiating a class from array of interfaces 2011-10-07

    SEE THE EDIT HALFWAY DOWN THE POST. I'm new to java and all the formal declarations of inheritance are getting me a little confused. I have a interface like so: public interface A{ public void one(); public void two(); } and then I have two classes l

  • I want to bind multiple concrete classes to an interface in Ninject 2012-01-10

    I want to bind multiple concrete classes to an interface in Ninject. I have ITestService interface and concrete implementations TestServiceA and TestServiceB. They are being bound like this: kernel.Bind<ITestService>().To<TestServiceA>();

  • Inject different classes that implement the same interface using Ninject 2011-12-21

    I am implementing the builder design pattern to construct different kinds of graph objects to be displayed on a WPF UI. I am using Ninject as my IOC container. However, I am trying to find an elegant extendable solution. I have a ChartDirector object

  • Property Injection in Base Controller using Ninject 2 2010-06-30

    I have the following code in my Global.aspx protected override void OnApplicationStarted() { AreaRegistration.RegisterAllAreas(); RegisterRoutes(RouteTable.Routes); RegisterAllControllersIn(Assembly.GetExecutingAssembly()); } protected override IKern

  • Inject IKernel as property in Ninject 2011-06-27

    I use a dependency resolver interface in common libraries as an abstraction. This keeps me flexible to switching containers. Given the interfaces and the static IoC class below, I need to initialize the IoC with a factory w/o passing the IKernel from

  • Injecting arrays with Unity 2011-11-18

    My goal is to constructor inject an array of objects implementing an interface. The following is the way I currently have it. Container .RegisterInstance<Company>(ParseCompany(args[1]) .RegisterInstance<eTargets>(ParseTargets(args[2])) .R

  • How to bind Generic-type interfaces in Ninject 2012-04-20

    I'm fairly new to Ninject, and found myself stumbling when I came to implement a generic repository pattern. I want to bind a dependency IRepository<IEntityType> to a class ConcreteRepository<EntityType> where ConcreteRepository<T>

  • dependency injection and logging interfaces 2009-02-06

    I was wondering what some of the best practices were around logging and logging frameworks and dependency injection. Specifically, if I am designing a class that needs a way to log, how should I go about getting an interface to log to keeping depende

  • Windsor Castle :- Inject Dictionary of Interfaces via configuration 2009-05-20

    Hi i am trying to inject a dictionary of interfaces but am getting an error from castle like this :- Castle.MicroKernel.SubSystems.Conversion.ConverterException: No converter registered to handle the type IFoo In order to go around the exception, I h

  • Injecting dependencies into WPF using Ninject 2009-07-20

    I have a WPF UserControl that I'd like to inject dependencies into. What's the best way to do this with Ninject? To take a concrete example: I have a UserControl called MapView, and I want to inject an instance of my IDialogueService into it, via eit

  • How to bind Assisted Injected class to interface? 2009-10-20

    Here is the problem I met: Class SimpleCommand implements Executable{ private final ConfigManager config; private String name; @Inject public SimpleCommand(ConfigManager config, @Assisted String name){ this.config = config; this.name = name; } } Clas

  • Is it wrong to transform/unserialize xml to an array to interface with it? 2010-02-11

    Consider a SOAP response with lots of nodes, I've noticed some developers using a PEAR Unserialize class while I've always been using simple_xml. Are there any disadvantages to interfacing if you aren't really doing any XML transformation or renderin

  • Connect items to a (specific index in) an array from Interface Builder 2010-12-09

    This one ought to be a softball for the Objective-C pros out there: Is there a way to connect an interface builder object to an element of an NSArray in Objective-C? The connecting would normally be done with IBOutlet, as in: @interface ViewControlle

  • Injecting infra layer interface in app service 2011-05-08

    I have two aggregates, Advertiser and Payment. I am using Paypal and Authorize.net payment gateway. So i created interface in infra layer. interface IPaymentMethod { void ProcessPayment(PaymentInfo paymentInfo); } and implemented it again in infra la

  • Getting a "WELD-001408 Unsatisfied dependencies error when deploying a class injected with an interface" 2011-05-19

    I'm doing some unit tests using Arquillian on JUnit4 and Jboss6. There is a facade(SomeFacadeclass) that has the "SomeClass"(which is an interface) injected to it. When Arquillian deploys the test.war for testing the above deployment error pops up. W

  • How to retrieve all bindings for a generic interface using Ninject 2011-11-11

    Using Ninject 2.2, I have the following failing test (simplified): public interface IGenericView<T> { } public interface IDefaultConvention { } public class DefaultConvention : IDefaultConvention { } public class DefaultConventionView : IGeneri

  • Invalid implicit cast when casting array of interfaces to an array of structs 2011-12-08

    I have a struct that implements some interface. This works fine until I have an array of the struct implementation and try to implicitly cast that array to another array of the interface type. (See the below code example) using System.Collections.Gen

Copyright (C) dskims.com, All Rights Reserved.

processed in 0.078 (s). 11 q(s)