【问题标题】:StructureMap DbContext with identity具有标识的 StructureMap DbContext
【发布时间】:2018-05-26 18:27:01
【问题描述】:

所以我最近开始使用结构图。我有一个使用身份的 web api。我的目标是每个请求都有一个 dbcontext。目前我遇到了上下文问题,通过结构映射注入的上下文与用户管理器使用的上下文不同。我环顾四周并找不到解决方案,尽管我确信它很明显。

所以首先我有我的结构图设置。

public class DefaultRegistry : Registry {
    #region Constructors and Destructors

    public DefaultRegistry() {
        Scan(
            scan => {
                scan.TheCallingAssembly();
                scan.AddAllTypesOf<IImporterService>().NameBy(type => type.Name);
                scan.WithDefaultConventions();
            });

        For<IHttpContextBaseWrapper>().Use<HttpContextBaseWrapper>();
        For<ApplicationDbContext>().Use(() => new ApplicationDbContext());
        For<HttpContextBase>().Use(() => new HttpContextWrapper(HttpContext.Current));
    }

    #endregion
}

我暂时不需要注入用户管理器,因为它是通过基础服务中的 httpcontext 访问的,我知道这可能需要更改以进行未来的单元测试。

接下来我们进行启动验证。

private void ConfigureOAuthTokenGeneration(IAppBuilder app)
    {
        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);

        //Token Auth
        var OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/api/account/login"),
            Provider = new ApplicationOAuthProvider("self"),
            AuthorizeEndpointPath = new PathString("/api/AccountApi/ExternalLogin"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(121),
            RefreshTokenProvider = new ApplicationRefreshTokenProvider(),
            //#if DEBUG
            AllowInsecureHttp = true,
            //#endif
        };

        // Enable the application to use bearer tokens to authenticate users
        app.UseOAuthBearerTokens(OAuthOptions);
    }

我已经减少了代码,但我有典型的服务和存储层结构。所有注入都使用结构映射,服务和存储库具有正确的上下文,唯一没有的是用户管理器。我知道它下面的行导致了这个问题:

app.CreatePerOwinContext(ApplicationDbContext.Create);

但是,就像我说的,我仍然习惯于构建映射,我之前使用了 unity,并且只会从当前容器中解析我需要的实例。非常感谢任何帮助或指导。

【问题讨论】:

  • 但为什么要投反对票?

标签: c# asp.net asp.net-identity structuremap


【解决方案1】:

您对所有这些行的问题:

    app.CreatePerOwinContext(ApplicationDbContext.Create);
    app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
    app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);

首先你告诉一个中间件来管理你的DbContext的创建。然后你告诉中间件来管理你的ApplicationUserManagerApplicationUserManager.Create 的创建由该中间件而不是你的DI 容器管理的ApplicationDbContext 实例。您的ApplicationRoleManager 也会发生同样的情况。最后,您有两种方法可以为每个请求生成ApplicationDbContext - 一种通过您的 DI 容器,另一种通过中间件。

如果您只想拥有ApplicationDbContext 的单个实例,则需要摆脱创建其实例的第二种方式:ApplicationDbContext.Create。这将解决您的问题。

但是您的中间件仍然需要访问您的ApplicationUserManager。所以代替所有这些:

   app.CreatePerOwinContext(ApplicationDbContext.Create);
   app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
   app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);

你需要使用app.CreatePerOwinContext(() =&gt; DependencyResolver.Current.GetService&lt;ApplicationUserManager&gt;());

除了从您的 DI 容器注入之外,摆脱所有其他创建这些实例的方法。

我的old blog post 中的更多信息 - 滚动到“清理”部分以了解有关中间件注册的详细信息。

【讨论】:

  • 谢谢你,你说得有道理。我之前实际上已经阅读过那篇博客文章:),只是关于这个主题有很多相互矛盾的信息。这就是我最初团结一致所做的事情,但我显然走错了路。我想处理我的上下文的中间件也会影响它的生命周期,可能会导致更多的内存使用?
  • 终身问题是的。记忆- 也是。但是每个请求只有另一个 DbContext 实例,而且很少使用。所以内存使用影响不是很明显。 (除非你在茶壶上运行它:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多