总结:
- 我已经定义了位于插件文件夹上的几个程序集上的未知IProducerPlugin实现。
- 我有一个核心对象存储当前注册用户的列表。
- 核心是组合根。
所以,我需要:
- 创建与注册用户数量一样多的IProducerPlugin继承类对象。
- 当一个新用户是un/registered时,我需要创建/释放这些对象。
为了注册我的"插件":
this.Kernel.Bind(b => b.FromAssembliesMatching("*")
.SelectAllClasses()
.InheritedFrom(typeof(Extensibility.IProducerPlugin))
.BindAllInterfaces());
我不太清楚如何实现这个。
你能帮我吗?
我非常感谢你的帮助。DI容器,特别是Ninject, 不适合在运行时向容器添加和删除新的绑定。有些(如Autofac)甚至不允许在创建容器后添加绑定。Ninject允许在任何时候添加新的绑定,但是你不能,永远,删除它们(*从一些用例中有Rebind
,但这是不一样的)。
kernel.Release(object)
并没有删除绑定,它只是删除了对object
的所有引用。例如:
var foo = new object();
kernel.Bind<object>().ToConstant(foo);
允许foo
的垃圾收集,您可以执行以下操作之一:
-
kernel.Release(foo);
-
kernel.Dispose(); kernel = null;
,这就是kernel.Release(...)
的作用。也许您还可以Release
一个单例,从而强制ninject在下一次请求时创建一个新的单例。但我不知道这是否真的有效,如果它确实有效,这肯定是一个意想不到的黑客。
所以你应该做的是自己管理列表/字典。你可以使用ninject绑定并注入列表/字典/管理器,不管你叫它什么,但是你不能让ninject管理器成为列表本身。
我已经设法做了类似的事情,使用这个IBindingGenerator接口方法…
我已经使用了.BindWith<>()
绑定方法…
this.Kernel.Bind(b => b.FromAssembliesMatching("*")
.SelectAllClasses()
.InheritedFrom(typeof(Extensibility.IProducerPlugin))
.BindWith<PluginBindingGenerator<Extensibility.IProducerPlugin>>()
);
我实现了一个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;
然后,提供者:
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(); }
}
}