Reputation: 23277
In summary:
So, I need:
In order to register my "plugins":
this.Kernel.Bind(b => b.FromAssembliesMatching("*")
.SelectAllClasses()
.InheritedFrom(typeof(Extensibility.IProducerPlugin))
.BindAllInterfaces());
I'm not quite figuring out how to implement this.
Could you help me please?
I'll appreciate a LOT your help.
Upvotes: 0
Views: 272
Reputation: 23277
I've managed to do something like that similar using this a IBindingGenerator interface method...
I've used .BindWith<>()
binding method...
this.Kernel.Bind(b => b.FromAssembliesMatching("*")
.SelectAllClasses()
.InheritedFrom(typeof(Extensibility.IProducerPlugin))
.BindWith<PluginBindingGenerator<Extensibility.IProducerPlugin>>()
);
I've implemented a IBindingGenerator:
public class PluginBindingGenerator<T> : IBindingGenerator
{
public System.Collections.Generic.IEnumerable<Ninject.Syntax.IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, Ninject.Syntax.IBindingRoot bindingRoot)
{
if (type != null && !type.IsAbstract && type.IsClass && typeof(T).IsAssignableFrom(type))
{
Ninject.Syntax.IBindingWhenInNamedWithOrOnSyntax<object> syntax = bindingRoot.Bind(typeof(Extensibility.IProducerPlugin)).ToProvider(new PluginProvider());
yield return (Ninject.Syntax.IBindingWhenInNamedWithOrOnSyntax<object>)syntax;
}
}
}
public class PluginProvider : IProvider<object>
{
private System.Collections.Generic.Dictionary<Domain.Identity.ClientIdentity, Extensibility.IProducerPlugin> plugins;
And then, the provider:
public PluginProvider()
{
this.plugins = new System.Collections.Generic.Dictionary<Domain.Identity.ClientIdentity, Extensibility.IProducerPlugin>();
}
public object Create(IContext ctx)
{
//... I don't know what to do here...
return objects;
}
public Type Type
{
get { throw new NotImplementedException(); }
}
}
Upvotes: 0
Reputation: 13243
DI containers in general and Ninject in special are not suitable to add and remove new bindings to the container during runtime. Some, like Autofac, don't even allow adding bindings once the container is created.
Ninject allows adding new bindings at any time, but you cannot, ever, remove them (*from some use cases there's Rebind
, but that's not the same).
kernel.Release(object)
is not removing the binding, it's only removing all references to the object
that it holds.
For example:
var foo = new object();
kernel.Bind<object>().ToConstant(foo);
to allow garbage collecting of foo
you can do one of the following:
kernel.Release(foo);
kernel.Dispose(); kernel = null;
and exactly this is what kernel.Release(...)
is for. Maybe you could also Release
a singleton and thus force ninject to create a new one on the next request. But i don't know whether this really works, and if it does, it certainly is quite an unexpected hack.
So what you should do is manage the list/dictionary yourself. You can bind and inject the list/dictionary/manager what ever you call it using ninject, but you cannot have ninject manager the list itself.
Upvotes: 1