我有一个Web API,并且将Autofac
用于DI。
在启动方法中,我正在使用app.CreatePerOwinContext (AppDbContext, UserManager and SignInManager).
配置身份验证,也在此处配置autofac
并注册控制器以及其他所需的类型和模块。
我还在DI上注册OwinContext
,并且在我的API使用的一个库中,我正在进行IOwinContext
的构造函数注入
当我发出第一个API请求时,Context.GetUserManager()可以正常工作,但是在第一个请求之后,它总是抛出“无法访问已处置的对象。\ r \ n对象名称:'ApplicationUserManager'。”
我的控制器是使用InstancePerRequest()注册的 我的图书馆是使用InstancePerLifetimeScope()注册的
如果我绕过API并直接调用我的库代码,则相同的代码可以在ASP.Net Web应用程序上正常工作。
我做了很多尝试,但是我无法找出合适的解决方案。
Startup.cs类(Web Api)
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
//Add cors middleware
app.UseCors(CorsOptions.AllowAll);
//http Configuration
var config = new HttpConfiguration();
WebApiConfig.Register(config);
//Configure authentication
ConfigureAuth(app);
//Configure DI Container
AutofacConfig.Register(app, config);
app.UseWebApi(config);
}
public void ConfigureAuth(IAppBuilder app)
{
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
}
}
DI注册
public class AutofacConfig
{
public static void Register(IAppBuilder app, HttpConfiguration config)
{
var builder = new ContainerBuilder();
builder.Register(c => HttpContext.Current.Request.GetOwinContext()).As<IOwinContext>();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly()).InstancePerRequest();
//this is in another module in different library which I am calling from here using builder.RegisterModule
builder.RegisterType<UserManager>().As<IManager<User>>().InstancePerLifetimeScope();
//Set the dependency resolver to be Autofac.
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
// Register the Autofac middleware FIRST, then the Autofac Web API middleware,
app.UseAutofacMiddleware(container);
app.UseAutofacWebApi(config);
}
}
这是我的UserManager
public class UserManager: IManager<User>
{
private ApplicationUserManager _applicationUserManager;
private readonly IOwinContext _context;
protected ApplicationUserManager ApplicationUserManager
{
get => _applicationUserManager ?? _context.GetUserManager<ApplicationUserManager>();
set => _applicationUserManager = value;
}
public UserManager(IOwinContext context)
{
_context = context;
ApplicationUserManager = context.GetUserManager<ApplicationUserManager>();
}
public User GetById(int? id)
{
//This throws System.ObjectDisposedException ('Cannot access a disposed object.Object name: 'ApplicationUserManager'.') after first API request.
var user = ApplicationUserManager.FindByEmail(entity.UserName);
return entity;
}
}
答案 0 :(得分:1)
我终于找到了问题所在。 UserManager由多个应用程序共享。 API和ASP.Net Web应用程序需要使用InstancePerRequest()注册 对于其他应用程序,我使用InstancePerLifetimeScope()注册了它。
创建一个带有构造函数参数的模块,如果该参数为true,则使用bool值并使用InstancePerRequest()注册UserManager,否则使用InstancePerLifetimeScope()。 这解决了我的问题。
基本上就是这种情况, 每次请求后,都会处理OwinContext中的ApplicationUserManager,但我的UserManager仍然与相同的OwinContext相同。
public class AutofacConfig
{
public static void Register(IAppBuilder app, HttpConfiguration config)
{
var builder = new ContainerBuilder();
builder.Register(c => HttpContext.Current.Request.GetOwinContext()).As<IOwinContext>().InstancePerRequest();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly()).InstancePerRequest();
//this is in another module in different library which I am calling from here using builder.RegisterModule
builder.RegisterType<UserManager>().As<IManager<User>>().InstancePerRequest();
//Set the dependency resolver to be Autofac.
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
// Register the Autofac middleware FIRST, then the Autofac Web API middleware,
app.UseAutofacMiddleware(container);
app.UseAutofacWebApi(config);
}
}