Jef*_*ger 4 .net ioc-container inversion-of-control async-await
我最近开始使用 ASP.NET 和 DynamoDB 在 C# 中编写大量异步/等待代码。我已经选择并设置Ninject作为我的 IoC 容器。从我在 Ninject 文档和在线搜索中找到的内容来看,Ninject 没有对异步的具体支持。这是有道理的,因为它是在 async/await 添加到 C# 之前编写的。然而,MSDN 上一篇关于异步编程最佳实践的文章推荐了“全程异步”方法。.NET 是否有支持异步解析和注册异步工厂的 IoC 容器?即,如果 Ninject 支持它,则kernel.GetAsync<IMyService>()
返回类似的内容Task<IMyService>
以及注册方法(例如kernel.Bind<IMyService>().ToMethod(ctx => factory.CreateAsync())
该CreateAsync
方法返回 a )Task<MyService>
,
实际上,我的 ASP.NET 异步代码出现了死锁,因为我被迫阻止异步代码(要了解为什么会发生这种情况,请参阅不要阻止异步代码)。我已经解决了这个问题,.ConfigureAwait(false)
但建议同时执行这两种方法以防止出现问题。另外,我被迫ConfigureAwait(false)
在一个无法证明我不需要上下文的地方添加,因为我正在调用一个将来可能会使用上下文的委托。
我有一个异步的用户存储库,因为它访问我的数据存储。
public interface IUserRepository
{
Task<User> GetAsync(Guid id);
}
Run Code Online (Sandbox Code Playgroud)
我将当前用户注册为依赖项,这样我就能够访问姓名、电子邮件等信息并进行安全检查。
kernel.Bind<User>().ToMethod(GetCurrentUser).InRequestScope();
// The implementation of GetCurrentUser
public static User GetCurrentUser(IContext context)
{
var repository = context.Kernel.Get<IUserRepository>();
var currentUserId = /* get current user id here from HttpContext.Current */;
return repository.GetAsync(currentUserId).Result; // blocks until the user is loaded
}
Run Code Online (Sandbox Code Playgroud)
这段代码在.Result
. 我真正需要的是能够返回Task<User>
并GetCurrentUser
让 Ninject 使用异步代码正确处理它。
据我所知,没有 IoC 容器支持async
. 我认为更好的国际奥委会和嘲笑支持async
是统治世界计划的下一个合乎逻辑的步骤async
。
如果你的用户存储库可以同步创建,那么你当然可以直接使用它:
var user = await context.Kernel.Get<IUserRepository>().GetAsync(currentUserId);
Run Code Online (Sandbox Code Playgroud)
然而,任何异步操作都必须在 IoC 容器“外部”完成。我有一篇关于async
构造函数的博客文章和一篇关于async
服务的 MSDN 文章,它们展示了当今处理这些情况的最佳方法。希望在不久的将来,有了真正的 IoCasync
支持,这种情况将会改变。
归档时间: |
|
查看次数: |
2996 次 |
最近记录: |