I have some code which inserts a candidate and then triggers an event to perform some other actions. Within the event there is code which should update the candidate, but it always fails because the candidate isn't being saved to the database until after the event. Here is the code:
[AbpAuthorize(RecruitmentPermissions.Recruitment_Candidates_Create)]
protected virtual async Task CreateCandidateAsync(CandidateEditDto input, bool suppressEvents = false)
{
var candidate = input.MapTo<Candidate>();
candidate.Id = Guid.NewGuid();
if (candidate.User.TenantId == null)
{
Abp.Authorization.Users.UserRole userRole = new Abp.Authorization.Users.UserRole()
{
RoleId = 3
};
candidate.User.TenantId = AbpSession.TenantId;
candidate.User.Name = input.FirstName;
candidate.User.Surname = input.Surname;
candidate.User.UserName = input.Username ?? input.EmailAddress;
candidate.User.Password = new PasswordHasher().HashPassword(input.Password);
candidate.User.IsActive = true;
candidate.User.EmailAddress = input.EmailAddress;
candidate.User.Roles = new List<Abp.Authorization.Users.UserRole>()
{
userRole
};
candidate.User.CreatorUserId = AbpSession.UserId;
}
// wait for insertion before firing event
_unitOfWorkManager.Current.Completed += (sender, args) =>
{
if (!suppressEvents)
EventBus.Trigger(new InsertCandidateEventData { candidate = candidate });
};
await _candidateRepository.InsertAsync(candidate);
}
According to the documentation, after InsertAsync has been run the unitOfWorkManager should then trigger my event - but it doesn't. I've tried saving manually (_unitOfWorkManager.Current.SaveChanges), and also putting the insert into it's own unit of work, but the database just isn't updated until CreateCandidateAsync has completed.
I'm quite new to ASP.Net Boilerplate, so any help anyone can give would be greatly appreciated. Thanks!
2 Answer(s)
-
0
Hi,
UOW is completed after your method (CreateCandidateAsync) is completed. Then your completed handler works. This is the expected behaviour. Isn't it works like that?
-
0
Hi Hikalkan. It looks like the InsertAsync is locking the database table until CreateCandidateAsync has fully completed, which means when the event tries to update the candidate it can't find it. A colleague suggested changing
_unitOfWorkManager.Current.Completed
to
_unitOfWorkManager.Current.Disposed
This ensures the event doesn't fire until after the candidate has been added to the database, but also means there is an error when attempting to update the candidate because the UserManagerProxy has been disposed of.
Is there a way I can recreate the UserManagerProxy, or stop it from being disposed of in the first place?