Reputation: 4157
I have two scenarios here that I want to solve with Ninject.Extensions.Conventions.
The first is a simple one: Whenever an instance from a namespace containing the word "service" is requested, return a singleton instance of the only matching class. I tried like so:
Kernel.Bind(service => service.FromThisAssembly()
.Select(theClass => theClass.Namespace.Contains("Service"))
.BindDefaultInterface()
.Configure(binding => binding.InSingletonScope()));
Some of those services get resolved, but I run into an ActivationException
when the resolution chain reaches a point where Impl1
has a dependency of IService2
.
What could be wrong with this binding?
The second one is probably equally simple. All classes that inherit BaseClass
should be instantiated via a method. This is the resolution code I used up to now, to do that per class:
Bind<MyViewModel>().ToMethod(ctx => fac.CreateProxy<MyViewModel>())
.InSingletonScope();
[ Note: In this case, fac is a custom factory that builds Castle proxies.]
How can I do such a thing for a classes inheriting from, say, ViewModelBase
with Extensions.Conventions
?
I figured out the select part already, here it is.
Kernel.Bind(ViewModel => ViewModel.FromThisAssembly()
.Select(t => t.BaseType == typeof(ViewModelBase))
);
Now I need to get that factory into action...
General Questions:
The binding approach of Extensions.Conventions seems to be the exact reverse of the regular way:
Ninject : Bind <Interface>() . To <Implementation> ()
Conventions : SelectAllClasses().BindDefaultInterface()
Why is that so, or a I misunderstanding this?
I used to put my bindings in a class derived from NinjectModule, and I'd preferrably continue to do so. Any reasons for not doing so when working with Extensions.Conventions
?
Upvotes: 2
Views: 1811
Reputation: 13233
first:
Please post the exact ActivationException message + Stacktrace.
Most likely the binding for IService2
is missing or there is a circular dependency.
second: Use a binding generator:
public override void Load()
{
this.Bind(x => x
.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<BaseClass>()
.BindWith<ToSelfProxyBindingGenerator>()
.Configure(binding => binding.InSingletonScope()));
}
public class ToSelfProxyBindingGenerator : IBindingGenerator
{
public IEnumerable<IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, IBindingRoot bindingRoot)
{
yield return bindingRoot
.Bind(type)
.ToMethod(ctx => fac.CreateProxy(type));
}
}
Also note that the singleton scope can be defined by the IBindingGenerator
or @ convention using the .Configure(..)
method.
General Questions:
Upvotes: 4