.net - 支持异步获取和异步实例创建的 IoC 容器

标签 .net inversion-of-control async-await ioc-container

我最近开始使用 ASP.NET 和 DynamoDB 在 C# 中编写大量异步/等待代码。我已经选择并设置了Ninject作为我的 IoC 容器。从我在 Ninject 文档和在线搜索中可以找到的内容来看,Ninject 没有对异步的特定支持。这是有道理的,因为它是在将 async/await 添加到 C# 之前编写的。但是,an article on MSDN about Best Practices in Asynchronous Programming 建议采用“一路异步”的方法。 .NET 是否有支持异步解析和注册异步工厂的 IoC 容器?即如果它在 Ninject 中受支持,类似于 kernel.GetAsync<IMyService>()返回 Task<IMyService>和像 kernel.Bind<IMyService>().ToMethod(ctx => factory.CreateAsync()) 这样的注册方法CreateAsync方法返回 Task<MyService> ,

示例/为什么需要这个

实际上,我的 ASP.NET 异步代码出现了死锁,因为我被迫阻塞了异步代码(要了解为什么会发生这种情况,请参阅 Don't Block on Async Code)。我用 .ConfigureAwait(false) 解决了这个问题但建议两者都做以防止出现问题。另外,我被迫添加ConfigureAwait(false)在一个无法证明我不需要上下文的地方,因为我正在调用一个可能在 future 使用上下文的委托(delegate)。

我有一个异步的用户存储库,因为它访问我的数据存储。

public interface IUserRepository
{
    Task<User> GetAsync(Guid id);
}

我将当前用户注册为依赖项,这样我就可以访问姓名、电子邮件等信息并进行安全检查。
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 
}

此代码在 .Result 上死锁.我真正需要的是能够返回 Task<User>来自 GetCurrentUser并让 Ninject 使用异步代码正确处理它。

最佳答案

据我所知,没有支持 async 的 IoC 容器。 .我认为对 async 的 IoC 和模拟支持更好是 async 计划中的下一个合乎逻辑的步骤统治世界。

如果您的用户存储库可以同步创建,那么您当然可以直接使用它:

var user = await context.Kernel.Get<IUserRepository>().GetAsync(currentUserId);

但是,任何异步操作都必须在 IoC 容器“外部”完成。我在 async constructors 上有一篇博文和一篇关于 async services 的 MSDN 文章这显示了当今处理这些情况的最佳方法。希望这会在不久的将来随着真正的 IoC async 而改变支持。

关于.net - 支持异步获取和异步实例创建的 IoC 容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23713774/

相关文章:

c# - Visual Studio 2010 WPF 设计器规模

java - 实现 Spring IOC 时如何避免使用 ApplicationContext.getBean()

javascript - 使用 async/await 组合并发和顺序请求

configuration - 为什么要在没有配置的情况下进行依赖注入(inject)?

javascript - Async-await 'Promise {<pending>} with Array.prototype.map

c# - 使用任务库的 Amazon S3 异步上传

c# - 流畅的断言 - 如何在类型检查后正确链接

c# - 在 Switch 语句中使用 .StartsWith?

.net - 如何在匹配表达式中使用 `&`?

.net - Windsor TypedFactoryFacility,根据参数类型选择组件