【问题标题】:Ninject - Intercept a multiple binding resolutionNinject - 拦截多重绑定解析
【发布时间】:2012-03-12 14:52:05
【问题描述】:

有没有办法让 Ninject 在遇到多个绑定解析问题时调用函数?

基本上,我想要这个:

static void Main(string[] args)
{
    StandardKernel k = new StandardKernel();
    k.Bind<IProvideConn>().To<probe1>(); // these bindings are actually done by assembly scanner, I don't know how many types are available
    k.Bind<IProvideConn>().To<probe2>();
    k.Bind<plugin1>().ToSelf();

    k.Get<plugin1>(); // Currently throws a "multiple bindings registered" exception
                      //but I would like it to call solveMyIssues.sortThingsOut
}

public class solveMyIssues
{
    public IBinding sortThingsOut(IEnumerable<IBinding> availableBindingsForThisResolve)
    {
        int i = AskChoiceFromUser(availableBindingsForThisResolve);
        return availableBindingsForThisResolve[i];
    }
}

interface IProvideConn0
{
    void goCrazy();
}

public class plugin1
{
    public void talkWithUser(IProvideConn0 pc)
    {
        pc.goCrazy();
    }
}

public class probe1 : IProvideConn0
{
    public void goCrazy() {}
}

public class probe2 : IProvideConn0
{
    public void goCrazy() {}
}

更多上下文:
我在像架构这样的插件中使用 Ninject。插件可以使用一种或多种类型的连接提供程序(每种连接提供程序类型都有一个继承自 IMotherConnProv 的接口)。
目前我使用 XML 扩展将每个 IProvideConnX 映射到一个实现(每个 IProvideConnX 可以有多个实现),但是当用户想要更改连接类型时,编辑 XML 文件非常繁琐。

我做了一个小应用程序,帮助他们用闪亮的按钮和所有东西修改 XML 文件,但我觉得应该有一种更动态的方法来做到这一点(Ninject 是关于让自己从 XML 中解放出来,对吧?)。
所以我想使用程序集扫描器来发现所有可能的选择,并以某种方式告诉 Ninject 在运行时选择哪个绑定(取决于用户选择)。

有什么想法吗? (我查看了that solution,但看不出如何使其适应无限数量的接口和实现)

【问题讨论】:

  • 那么当配置了多个IProvideConn 时,您想要发生什么?它应该绑定到哪一个?
  • 用户选择的那个。然后我可以提供一种机制来保存/恢复选择。

标签: .net dependency-injection ninject


【解决方案1】:

不,你不能。但是您可以配置您的绑定,使其不会发生:

kernel.Bind(
    x => x.FromThisAssembly()
          .SelectAllClasses().InheritedFrom<IProvideConn0>()
          .BindToAllInterfaces()
          .Configure((binding, componentType) => b.When(r => kernel.Get<IConfiguration>().ConnectionType == componentType.Name)));
kernel.Bind(
    x => x.FromThisAssembly()
          .SelectAllClasses().InheritedFrom<IConnectionType>()
          .BindToAllInterfaces();

public class Configuration : IConfiguration
{
    public Configuration(IEnumerable<IConnectionType> connectionTypes) { ... }

    public string ConnectionType
    {
        get 
        {
            return this.UserWhichConnectionDoYouWant(connectionTypes);
        }
    }
}

并为每个连接添加一个 IConnectionType 指定必要的信息以让用户选择它。

https://github.com/ninject/ninject.extensions.conventions/wiki/What-is-configuration-by-conventions

【讨论】:

  • 看起来很不错!但我不知道如何使用它,kernel.Bind 似乎不接受委托(我使用的是 ninject 2.2 和约定扩展)。我查看了约定扩展中的单元测试,但在任何地方都找不到该语法,您还有其他示例吗?
  • 基本上,这不会构建:使用 Ninject;使用 Ninject.Planning.Bindings;使用 Ninject.Extensions.Conventions;使用 System.Reflection;类程序 { static void Main(string[] args) { using (IKernel kernel = new StandardKernel()) { kernel.Bind( x => x.From(Assembly.GetExecutingAssembly()) .SelectAllTypes() .BindToDefaultInterface() 。配置((绑定,componentType)=> b.When(r => true))); } }
  • 这需要 3.0 形式的 NuGet (Install-Package Ninject.Extensions.Conventions -pre)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-29
相关资源
最近更新 更多