如何使用Ninject约定绑定服务

时间:2014-03-04 07:59:55

标签: dependency-injection ninject conventions ninject-extensions

我想在这里使用Ninject.Extensions.Conventions解决两个场景。

第一个是一个简单的:每当请求来自包含单词“service”的命名空间的实例时,返回唯一匹配类的单例实例。我试过这样:

Kernel.Bind(service => service.FromThisAssembly()
                              .Select(theClass => theClass.Namespace.Contains("Service"))
                              .BindDefaultInterface()
                              .Configure(binding => binding.InSingletonScope()));

其中一些服务已得到解决,但当解决方案链达到ActivationException依赖Impl1的点时,我会遇到IService2

这种绑定可能有什么问题?


第二一个可能同样简单。所有继承BaseClass的类都应该通过方法实例化。这是我到目前为止使用的解决方案代码,每个类都要这样做:

Bind<MyViewModel>().ToMethod(ctx => fac.CreateProxy<MyViewModel>())
                   .InSingletonScope();

[注意:在这种情况下,fac是一个自定义工厂,可以构建Castle代理。]

我怎样才能为从ViewModelBase继承Extensions.Conventions的类继承这样的事情?

我已经找到了选择部分,就在这里。

Kernel.Bind(ViewModel => ViewModel.FromThisAssembly()
                                  .Select(t => t.BaseType == typeof(ViewModelBase))
                                  );

现在我需要让这家工厂付诸行动......


一般问题:

  1. Extensions.Conventions的绑定方法似乎与常规方式完全相反:

    • Ninject:Bind <Interface>() . To <Implementation> ()

    • 约定:SelectAllClasses().BindDefaultInterface()

      为什么会这样,或者我误解了这个?

  2. 我曾经把我的绑定放在一个派生自NinjectModule的类中,我宁愿继续这样做。使用Extensions.Conventions

  3. 时有任何理由不这样做

1 个答案:

答案 0 :(得分:4)

<强>第一: 请发布确切的ActivationException消息+ Stacktrace。 很可能缺少IService2的绑定或存在循环依赖。

<强>第二: 使用绑定生成器:

    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));
        }
    }

另请注意,单一作用域可以使用IBindingGenerator方法由.Configure(..)或@约定定义。

一般问题

  1. 你是对的,但我无法告诉你背后的确切原因。
  2. 将约定放入不同的模块是不是很好。我们也这样做,而且效果很好。