c# - 具有标识的 StructureMap DbContext
问题描述
所以我最近开始使用结构图。我有一个使用身份的 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);
但是,就像我说的那样,我仍然习惯于构建地图,我以前使用过统一,并且只会从当前容器中解析我需要的实例。非常感谢任何帮助或指导。
解决方案
您对所有这些行的问题:
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
首先你告诉一个中间件来管理你的DbContext
. 然后你告诉中间件管理你的创建,ApplicationUserManager
并获取一个由该中间件管理ApplicationUserManager.Create
的实例,而不是你的 DI 容器。ApplicationDbContext
你的ApplicationRoleManager
. 最后,您有 2 种方式来生成ApplicationDbContext
每个请求 - 一种通过您的 DI 容器,另一种通过中间件。
如果您只想拥有一个实例,则ApplicationDbContext
需要摆脱第二种创建其实例的方式:ApplicationDbContext.Create
. 这将解决您的问题。
但是,您的中间件仍然需要访问您的ApplicationUserManager
. 所以代替所有这些:
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
你需要使用app.CreatePerOwinContext(() => DependencyResolver.Current.GetService<ApplicationUserManager>());
除了从您的 DI 容器注入之外,摆脱所有其他创建这些实例的方法。
我的旧博客文章中的更多信息- 滚动到“清理”部分以获取有关中间件注册的详细信息。
推荐阅读
- sql - SAS - 创建增量表
- couchbase - Couchbase N1QL:GROUP BY CASE 子句不起作用
- reactjs - React/Redux 重复组件无法访问操作
- java - 奇怪的 Java 类型安全不适用于集合
- php - 如何从对象(集合)中获取价值?
- dataframe - Julia:如何通过索引从数据框中删除多行
- javascript - 如何确定用户何时在输入中键入“@”
- arrays - 如何在Angular 8中选择下拉列表时生成表格
- r - 如何对 R 中具有不同维度的两个数据框求和
- python - 检查特定的 Checkbutton 还会检查 Tkinter 中的另一个复选框