无法访问已处置的对象。\ r \ n对象名称:“ ApplicationUserManager”

时间:2019-08-29 15:08:31

标签: c# asp.net-web-api asp.net-identity owin autofac

我有一个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;
        }
   }

1 个答案:

答案 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);
        }
    }