[ninject] Binding open generic types to generic providers?

828 views
Skip to first unread message

Aaron G

unread,
Apr 23, 2010, 3:28:54 PM4/23/10
to ninject
Apologies if this has already been asked, I wasn't able to find any
other references to this.

I sometimes need to bind open generics, which works fine using the
syntax:

Bind(typeof(IFoo<>)).To(typeof(MyFoo<>));

Now I'm trying to get this to work using a provider:

Bind(typeof(IFoo<>)).ToProvider(MyFooProvider<>));

Ninject doesn't seem to like this very much. When I try to get an
instance of IFoo<T>, I get an ActivationException that says "Error
activating FooProvider{T}. No matching bindings are available, and the
type is not self-bindable."

What's odd is that if I make the provider type self-bindable, i.e.
with:

Bind(typeof(MyFooProvider<>)).ToSelf();

Then I get the same exception but with the message "More than one
matching bindings are available."

Is this scenario supported in Ninject? If so, how do I do it? And if
not, what would be an appropriate workaround?

(P.S. Using the latest build from git - 2.0.1.0)

--
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.

Remo Gloor

unread,
Apr 26, 2010, 1:12:25 PM4/26/10
to ninject
Hi

ToProvider currently doesn't support open generics.

You have two Options to solve the problem:
1. Patch Ninject BindingBuilder to add open generic provider support:
public IBindingWhenInNamedWithOrOnSyntax<T> ToProvider(Type
providerType)
{
Binding.ProviderCallback = ctx => ctx.GenericArguments ==
null
?
ctx.Kernel.Get(providerType) as IProvider
:
ctx.Kernel.Get(providerType.MakeGenericType(ctx.GenericArguments)) as
IProvider;
Binding.Target = BindingTarget.Provider;
return this;
}

2. Use ToMethod Instead
Bind(typeof(IFoo<>)).ToMethod(ctx =>
(ctx.Kernel.Get(typeof(MyFooProvider<>).MakeGenericType(ctx.GenericArguments))
as IProvider).Create(ctx));

But be aware that both options currently do not check if the generic
arguments of the requested type match the providers generic argument
list. A proper implementation will need to check for that as well.

Regards
Remo
Reply all
Reply to author
Forward
0 new messages