【问题标题】:Can I use async method for Ninject bindings using ToMethod?我可以使用 ToMethod 对 Ninject 绑定使用异步方法吗?
【发布时间】:2013-04-10 10:59:17
【问题描述】:

我目前正面临对象异步初始化的问题 (this question)。我正在使用 Ninject 3.0.1.10,我想实现以下目标:

Kernel.Bind<IServiceProvider>().ToMethod(async ctx => await ServiceProvider.CreateAsync())

现在这个东西不能编译,因为异步 lambda 表达式返回一个Task&lt;ServiceProvider&gt;,而不是ServiceProvider。有没有办法在 Ninject 中异步初始化对象?也许有一些解决方法?

【问题讨论】:

  • 你试过Task.Wait(/*...*/)吗?
  • 那么它将是同步的......但是你是对的,这种异步必须在某个地方表现出来。我猜,Kernel.Get() 那么也应该是异步的。 Ninject 有可能吗?
  • 有两种方法可以将注入与 IServiceProvider 的实例化解耦。第一个是:注入 Lazy。这由 ninject 支持,但意味着 IServiceProvider 消费者知道它。第二个是将 IServiceProvider 绑定到接口的代理,因为对代理的第一次调用必须检索实际实例(或再次在 Lazy 上执行它)。但是请注意,默认情况下 ninject 会为每个类型创建一个代理,而不是每个实例。我有一个解决方法。如果您希望我发布完整的解决方案,请告诉我。
  • @BatteryBackupUnit 是的,请发布您的解决方案。我想,一些解决方法不会有什么坏处,因为这个问题还没有任何答案。

标签: c# windows-phone-8 ninject


【解决方案1】:

根据您的要求,我发布了一个使用 ninject 的解决方案。 我稍微偏离了你的目标,因为构造函数没有执行初始化,而是一个方法。该方法由拦截器调用。 Async-Ctor 最有可能通过更改为“没有目标的接口代理”(参见http://docs.castleproject.org/Tools.Kinds-of-proxy-objects.ashx)并让拦截器实例化对象来实现。

我还想说,我相信异步初始化可能会带来比好处更多的缺点。例如,处理初始化异常会很困难,因为对接口的任何调用都可能导致初始化异常。

IFoo 绑定到InterceptingProxyProvider : IProvider。提供者实例化FooFoo 的所有拦截器,然后创建并返回城堡动态代理(Proxy)。 这是Caller 在注入IFoo 时收到的内容。 AsyncInitializationInterceptor 在其构造函数中启动 Foo 的初始化。 在第一次拦截调用时,它等待初始化完成,然后继续。 如果初始化失败并出现异常,所有对IFoo 的进一步访问都将导致引发初始化异常。

进一步说明,ninject 代理扩展为每个目标类型创建一个拦截器实例。但是,我们想要的是每个目标实例一个拦截器实例。这就是为什么我提供了代理和拦截器的绑定和实例化的自定义实现。

这里是代码,完整的集成测试应该会告诉你如何使用它:

【讨论】:

  • 有人可以在代码中发布答案吗?我无法访问这两个网址,我真的很想使用带有 ninject 的异步库。
  • 解决方案包含不少源文件。我可以将它们添加到答案中,但这意味着您必须将大量文件添加到解决方案/c# 项目中。相反,我也可以将它上传到另一个文件托管商——以防万一您可以访问?请告诉我。
  • 就是这样,也许 github repo 最好?大多数文件共享网站在这里都被 IT 屏蔽了,但 github 还可以。谢谢您的答复。我也主要是在查看了粗略的实现之后。如果是一大堆文件,可能是 github repo/nuget 包 :)
  • @user1570690 github 仓库现已推出:github.com/BrunoJuchli/NinjectAsyncInitializationByInterception
猜你喜欢
  • 1970-01-01
  • 2014-05-19
  • 2014-08-06
  • 1970-01-01
  • 2022-12-09
  • 1970-01-01
  • 2021-07-25
  • 2018-03-04
  • 2017-09-07
相关资源
最近更新 更多