我有一个多租户MVC5 webapp,它使用的是Autofac v3.5.2和Autofac.Mvc5 v3.3.4。
我的Autofac DI接线在我的MVC项目中的一个班级中进行。对于身份验证,我们使用OWIN OpenId middleware与Azure B2C集成。在OWIN Startup类中,我需要依赖项来使用当前请求中的信息设置tenantId
/ clientId
。
我试图通过以下方式获取依赖:
DependencyResolver.Current.GetService<...>();
但是,这总是会引发ObjectDisposedException
无法解析实例,并且无法从此LifetimeScope创建嵌套生命周期,因为它已经被处理掉了。
我们的应用程序中有一个ISiteContext,它有一个请求生命周期。它将填充特定于当前请求的配置值。我试图像这样获取这些值:
private OpenIdConnectAuthenticationOptions CreateOptionsFromPolicy(string policy)
{
var options = new OpenIdConnectAuthenticationOptions
{
Notifications = new OpenIdConnectAuthenticationNotifications
{
...
RedirectToIdentityProvider = SetSettingsForRequest
}
}
}
private Task SetSettingsForRequest(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context)
{
var siteContext = DependencyResolver.Current.GetService<ISiteContext>();
context.ProtocolMessage.ClientId = siteContext.ClientId;
return Task.FromResult(0);
}
尝试在SetSettingsForRequest中使用DependencyResolver时发生错误。我不知道我在这里做错了什么。目前我的启动Configuration(IAppBuilder app)
方法中没有 Autofac DI设置,因为这已经在我的MVC项目中设置。
答案 0 :(得分:1)
正如MickaëlDerriey所指出的,以下代码是能够解决OWIN中请求范围依赖关系的解决方案:
public class Startup
{
public void Configuration(IAppBuilder app)
{
var builder = new ContainerBuilder();
// Register dependencies, then...
var container = builder.Build();
// Register the Autofac middleware FIRST. This also adds
// Autofac-injected middleware registered with the container.
app.UseAutofacMiddleware(container);
// ...then register your other middleware not registered
// with Autofac.
}
}
然后在任何后续代码中使用来解决依赖关系:
// getting the OWIN context from the OWIN context parameter
var owinContext = context.OwinContext;
var lifetimeScope = owinContext.GetAutofacLifetimeScope();
var siteContext = lifetimeScope.GetService<ISiteContext>();
context.ProtocolMessage.ClientId = siteContext.ClientId;
使用此解决方案,我不再有任何问题解决请求范围的依赖关系,因为Autofac似乎符合OWIN创建/处理请求范围的方式。
答案 1 :(得分:0)
我担心此时您需要在OWIN管道中设置DI。这不是一项艰难的行动。
你必须:
Global.asax.cs
Startup.cs
,因为上面链接的文档显示这样做意味着Autofac将在OWIN级别创建堆栈中较低的每请求生命周期范围。这将允许您从OWIN上下文中获取HTTP请求生存期范围:
private Task SetSettingsForRequest(RedirectToIdentityProviderNotification<OpenIdConnectMessage, OpenIdConnectAuthenticationOptions> context)
{
// getting the OWIN context from the OIDC notification context
var owinContext = context.OwinContext;
// that's an extension method provided by the Autofac OWIN integration
// see https://github.com/autofac/Autofac.Owin/blob/1e6eab35b59bc3838bbd2f6c7653d41647649b01/src/Autofac.Integration.Owin/OwinContextExtensions.cs#L19
var lifetimeScope = owinContext.GetAutofacLifetimeScope();
var siteContext = lifetimeScope.GetService<ISiteContext>();
context.ProtocolMessage.ClientId = siteContext.ClientId;
return Task.FromResult(0);
}
我希望这有助于你克服这个问题。