简体   繁体   English

OWIN WebAPI简单注入器EFCoreInMemoryDB注入

[英]OWIN WebAPI Simple Injector EFCoreInMemoryDB injection

Im building a service using OWIN and I want to inject EF core in memory db using UserDbContext(DBOptions) 我正在使用OWIN构建服务,我想使用UserDbContext(DBOptions)将EF内核注入内存db中

Startup.cs: Startup.cs:

public void Configuration(IAppBuilder appBuilder)
{
    HttpConfiguration config = new HttpConfiguration();
    config.MapHttpAttributeRoutes();

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );

    var container = new Container();
    container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();

    // How to Register In memory DB?!
    // I get an exception on DbContextOptions< in UserContext

    container.Register<DbContext>(() => {
        var optionsBuilder = new DbContextOptionsBuilder<UserContext>()
            .UseInMemoryDatabase("UserContext");
        return new UserContext(optionsBuilder.Options);
    });

    container.Register<IUserRepository, UserRepository>();

    config.DependencyResolver =
        new SimpleInjectorWebApiDependencyResolver(container);

}

I got far enough so that I do not get an exception on starting the service. 我已经走了很多,以至于在启动服务时没有异常。 But when I call API I get an exception saying: 但是当我调用API时,出现了一个异常:

The constructor of type UserContext contains the parameter with name 'options' and type DbContextOptions<UserContext> that is not registered. UserContext类型的构造函数包含名称为“ options”的参数,并且类型DbContextOptions <UserContext>未注册。 Please ensure DbContextOptions<TUserContext> is registered, or change the constructor of UserContext 请确保DbContextOptions <TUserContext>已注册,或更改UserContext的构造函数

UserRepository.cs UserRepository.cs

public class UserRepository : IUserRepository
{
    private readonly UserContext context;

    public UserRepository(UserContext context)
    {
        this.context = context;
    }
}

UserContext.cs UserContext.cs

public class UserContext : DbContext
{
    public UserContext(DbContextOptions<UserContext> options)
      : base()
    {
    }

    public DbSet<User> Users { get; set; }
}

So how do you register in ef core memory db, with UserContext using Simple Injector? 那么,如何使用Simple Injector通过UserContext在ef核心内存db中注册? It would be super easy to do this using standard .NET Core DI. 使用标准的.NET Core DI做到这一点将非常容易。

The error happens because you didn't register UserContext , but only DbContext . 发生错误是因为您没有注册UserContext ,而只有DbContext Change your container.Register<DbContext>(...) registration to the following: 将您的container.Register<DbContext>(...)注册更改为以下内容:

container.Register<UserContext>(() => ...);

Also note that you currently registered the UserContext using the Transient lifestyle, while the most typical lifestyle for a DbContext is Scoped : 还要注意,您当前使用的是Transient生活方式注册UserContext ,而DbContext的最典型生活方式是Scoped

container.Register<UserContext>(() => ..., Lifestyle.Scoped);

It would be super easy to do this using standard .NET Core DI. 使用标准的.NET Core DI做到这一点将非常容易。

It is super easy with Simple Injector as well :) With Core DI you basically need the same registration. 使用简单进样器也非常容易:)使用Core DI,您基本上需要相同的注册。

The thing that confused you, is that Simple Injector v4, by default, tries to instantiate concrete unregistered dependencies for you. 让您感到困惑的是,默认情况下,Simple Injector v4会尝试为您实例化未注册的具体依赖关系。 UserContext was not registered, while being concrete. UserContext未注册。 Simple Injector tries to create it, but it found that it couldn't resolve one of its dependencies. Simple Injector尝试创建它,但是发现它无法解析其依赖项之一。 That's why the error message points at DbContextOptions<UserContext> , instead the error being "you didn't register UserContext". 这就是错误消息指向DbContextOptions<UserContext> ,而错误是“您没有注册UserContext”。

To fix this, this "resolution of unregistered concrete types" behavior will change starting from v5. 要解决此问题,此“未注册的具体类型的解析”行为将从v5开始更改。 v5 will, by default, not resolve unregistered concrete types any longer. 默认情况下,v5将不再解析未注​​册的具体类型。 This is safer and would result in a more obvious exception message. 这样比较安全,并且会导致出现更明显的异常消息。

With the introduction of Simple Injector v4.5, we introduced an option that allows you to switch to the coming v5 behavior. 随着Simple Injector v4.5的引入,我们引入了一个选项,使您可以切换到即将到来的v5行为。 My advice is to use this new setting right away, as it's safer behavior and prevents you from experiencing errors once you switch to v5. 我的建议是立即使用此新设置,因为这是更安全的行为,可以防止您在切换到v5后遇到错误。 You can do this as follows: 您可以按照以下步骤进行操作:

var container = new Container();

container.Options.ResolveUnregisteredConcreteTypes = false;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM