正如我最近发表的大部分文章一样,我首先要说这对我来说是全新的,我处于理解的边缘。我正在处理现有的应用程序,并遇到了上述错误。
该应用程序是一个MVC应用程序,有3层,正在通过Swagger运行:
Rest
Services
DAL
在服务层DependencyConfig
中,我在Register
方法中执行以下操作,注册了上下文:
container.RegisterWebApiRequest<DbContext>(() => new LocalContext("name=DefaultConnection"));
到目前为止,这一切似乎都运行良好,因为应用程序的一部分是从数据库读取和写入 - 虽然这个应用程序中有很多东西,但我并不了解所有这些。
接下来,在Rest层上,我有以下内容:
public class AccountController : ApiController
{
private readonly WindowsAuthenticationProvider _windowsAuthentication;
private readonly AuthorizationManager _authorizationManager;
private readonly IApplicationUserService _userService;
private readonly IProfileService _profileService;
private readonly IAccountLogsService _accountLogsService;
/// <summary>
/// Constructor
/// </summary>
/// <param name="authorizationManager">Authorization Manager</param>
/// <param name="windowsAuthentication">Enables windows reauthentication without a session</param>
public AccountController(AuthorizationManager authorizationManager, WindowsAuthenticationProvider windowsAuthentication,
IApplicationUserService userService, IProfileService profileService, IAccountLogsService accountLogsService)
{
_windowsAuthentication = windowsAuthentication;
_authorizationManager = authorizationManager;
_userService = userService;
_profileService = profileService;
_accountLogsService = accountLogsService;
}
/// <summary>
/// Get logged in user details
/// </summary>
/// <remarks>Retrieves details of the currently logged in user</remarks>
[Authorize]
[HttpGet]
[Route("")]
[ResponseType(typeof(AccountDetailsModel))]
public IHttpActionResult Details()
{
var userId = User.Identity.GetUserId<int>();
var model = //...
if (model.HasAccount)
{
var user = _authorizationManager.FindUser(User.Identity);
}
return Ok(model);
}
}
以及服务层:
public class AuthorizationManager
{
private readonly IApplicationUserService _userService;
public ApplicationUser FindUser(IIdentity identity)
{
var userId = identity.GetUserId<int>();
if (userId != 0)
{
return _userService.FindById(userId);
}
//...
}
}
最后也在服务层:
public class ApplicationUserService : UnitOfWork<LocalContext>, IApplicationUserService
{
private readonly UserManager<ApplicationUser, int> _userManager;
private readonly RoleManager<ApplicationRole, int> _roleManager;
/// <summary>
/// Finds a user by id
/// </summary>
/// <param name="id">User id</param>
/// <returns>ApplicationUser</returns>
public ApplicationUser FindById(int id)
{
return _userManager.FindById(id);
}
}
其中ApplicationUser
是DAL图层上的模型。
我希望到目前为止这一切都有意义!
问题是当代码到达这一行时:
return _userManager.FindById(id);
它会抛出InvalidOperationException: The operation cannot be completed because the DbContext has been disposed.
在我看来,它已经失去了上下文,例如数据库连接。
它似乎从寄存器方法中处理了DbContext - 但我不明白为什么?
如果我手动创建这样的上下文:
Context.Users.Find(id);
我能够检索所需的条目,但问题又发生在线下 - 而且我认为该应用程序的目的不是这样。
所以我的问题是,为什么要处理我的上下文,我怎么能阻止它呢?
单步执行代码并没有帮助,我的想法也没有。
答案 0 :(得分:0)
问题与这条线有关:
container.Register<IUserStore<ApplicationUser, int>, UserStore <ApplicationUser, ApplicationRole, int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>>(Lifestyle.Scoped);
由于lifestlye.scoped,此时正在处理背景。
我需要将其添加到container
:
container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();
来自这些说明:http://simpleinjector.readthedocs.io/en/latest/lifetimes.html#perwebrequest
仅在Web请求结束处理了对象