【问题标题】:Cannot access a disposed object.\r\nObject name: 'ApplicationUserManager'无法访问已释放的对象。\r\n对象名称: 'ApplicationUserManager'
【发布时间】:2020-01-02 21:37:50
【问题描述】:

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

这是我的用户管理器

 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;
        }
   }

【问题讨论】:

  • 这篇文章对你有帮助:stackoverflow.com/questions/32288506/…,正确注入ApplicationUserManager
  • 正如您在我的帖子中所读到的,ApplicationUserManager 是可用的,并且不会在对 API 的第一次请求时处理。后续请求失败。

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


【解决方案1】:

我终于找到了问题所在。 UserManager 被多个应用程序共享。 API 和 ASP.Net Web 应用程序需要使用 InstancePerRequest() 进行注册 对于其他应用,我使用 InstancePerLifetimeScope() 注册了它。

使用构造函数参数创建一个模块,如果参数为真,则使用布尔值并使用 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);
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-25
    • 1970-01-01
    • 2022-01-11
    • 2020-04-23
    • 2017-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多