c# - 简单注入(inject)器在 Owin 启动期间无法注入(inject)每个 Web API 请求注册类

标签 c# asp.net-web-api dependency-injection owin simple-injector

我正在使用 Owin、Web API、Entity Framework、ASP.NET Identity 创建 API。我正在使用 Simple Injector作为我选择的 DI 框架。

在 Owin 启动过程中,我想用一些样本数据为我的数据库做种。这是由实现 IDatabaseInitializer 的类处理的,它看起来像这样:

public class MyDbInitializer : DropCreateDatabaseAlways<MyDataContext>
{
    private readonly IUserManager _userManager;

    public MyDbInitializer(IUserManager userManager)
    {
        _userManager = userManager;
    }

    protected override void Seed(MyDataContext context)
    {
        SeedIdentities();
    }

    private void SeedIdentities()
    {
        var user = new User
        {
            UserName = "someUsername",
            Email = "some@email.com"
        };

        _userManager.CreateAsync(user, "Password");
    }

IUserManager 是 ASP.NET Identiy UserManager 类的代理,它间接依赖于 IUnitOfWork。如果您想知道,IUserManager 是这样注册的:

container.Register(typeof(IUserManager), 
    () => container.GetInstance<IUserManagerFactory>().Create());

因为我想对每个 Web API 请求使用一个工作单元,所以我注册了我的 IUnitOfWork,如下所示:

container.RegisterWebApiRequest<IUnitOfWork, MyUnitOfWork>();

除了解析 MyDbInitializer 类中的 IUserManager 依赖项之外,这对所有事情都工作得很好。在应用程序启动期间,SimpleInjector 失败并出现以下 ActivationException:

SimpleInjector.ActivationException was unhandled by user code
  HResult=-2146233088
  Message=The registered delegate for type IUserManagerFactory threw an exception. The IUnitOfWork is registered as 'Web API Request' lifestyle, but the instance is requested outside the context of a Web API Request.
   Source=SimpleInjector
   StackTrace:
     at SimpleInjector.InstanceProducer.GetInstance()
     at SimpleInjector.Container.GetInstance[TService]()
     at Project.WebApi.CompositionRoot.SimpleInjectorCompositionRoot.<RegisterSecurityDependencies>b__c() in c:\code\Project\Project.WebApi\CompositionRoot\SimpleInjectorCompositionRoot.cs:line 130
     at lambda_method(Closure )
     at lambda_method(Closure )
     at SimpleInjector.InstanceProducer.GetInstance()
   InnerException: SimpleInjector.ActivationException
     HResult=-2146233088
     Message=The IUnitOfWork is registered as 'Web API Request' lifestyle, but the instance is requested outside the context of a Web API Request.
     Source=SimpleInjector
     StackTrace:
        at SimpleInjector.Scope.GetScopelessInstance[TService,TImplementation](ScopedRegistration`2 registration)
        at SimpleInjector.Scope.GetInstance[TService,TImplementation](ScopedRegistration`2 registration, Scope scope)
        at SimpleInjector.Advanced.Internal.LazyScopedRegistration`2.GetInstance(Scope scope)
        at lambda_method(Closure )
        at SimpleInjector.InstanceProducer.GetInstance()
     InnerException:

我猜 Owin Startup.cs 类被认为在 Web API 请求生命周期之外,并且数据库初始化程序中的构造函数注入(inject)失败,因为它被 Startup 调用。 cs 类。

我不确定如何解决这个问题。我应该使用混合生活方式来注册 IUnitOfWork,还是有更好的解决方案?

最佳答案

你是对的。在启动过程中,没有 Web API 请求。幸运的是,WebApiRequestLifestyle (由 RegisterWebApiRequest 扩展方法使用)使用 ExecutionContextLifestyle在幕后,因此“模拟”网络请求非常简单,如下所示:

// using SimpleInjector.Extensions.ExecutionContextScoping;

using (container.BeginExecutionContextScope())
{
    var initializer = container.GetInstance<MyDbInitializer>();
    intializer.InitializeDatabase();
}

关于c# - 简单注入(inject)器在 Owin 启动期间无法注入(inject)每个 Web API 请求注册类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25402872/

相关文章:

c# - 使用 ITextSharp 获取 PDF 中图像的位置(X、Y、宽度、高度)

asp.net - 使用 Web API 服务作为中央身份验证点

c# - Asp.Net Web API 路由 - 必需的 QueryString 参数

C# HttpClient 发布信息不等待响应

java - 理解Spring注解DI

c# - 打开目标类型未知的实例委托(delegate)?

c# - Asp.Net MVC - 在数据库中插入多行

c# - Active Directory 组在创建后无法立即可用

c# - 使用依赖注入(inject)将配置代码保留在逻辑代码之外的方法

php - 如何在 Aura.Di 中容器化构建器类?