NInject:根据约定绑定为每个用户/会话创建实例



总结:

  1. 我已经定义了位于插件文件夹上的几个程序集上的未知IProducerPlugin实现。
  2. 我有一个核心对象存储当前注册用户的列表。
  3. 核心是组合根。

所以,我需要:

  1. 创建与注册用户数量一样多的IProducerPlugin继承类对象。
  2. 当一个新用户是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(); }
    }
}

最新更新