What is the recommended way to run asp.net identity functions in transaction?

一世执手 提交于 2019-12-23 15:26:30

问题


Using asp.net identity RTW version.

I need to perform several actions in a transaction, including both UserMananger function calls and other operations on my DbContext (example: create new user, add it to group and perform some business-logic operations).

How should I do this?

My thoughts follow.

TransactionScope

using (var scope = new TransactionScope(TransactionScopeOption.Required))
{
    // Do what I need
    if (everythingIsOk) scope.Complete();
}

The problem is: UserManager functions are all async, and TransactionScope was not designed to work with async/await. It seems to be solved in .Net Framework 4.5.1. But I use Azure Web Sites to host my project builds, so I cannot target 4.5.1 yet.

Database transaction

public class SomeController : Controller
{
    private MyDbContext DbContext { get; set; }
    private UserManager<User> UserManager { get; set; }

    public AccountController()
    {
        DbContext = new MyDbContext()
        var userStore = new UserStore<IdentityUser>(DbContext);
        UserManager = new UserManager<IdentityUser>(userStore);
    }

    public async ActionResult SomeAction()
    {
        // UserManager uses the same db context, so they can share db transaction
        using (var tran = DbContext.Database.BeginTransaction())
        {
            try
            {
                // Do what I need
                if (everythingIsOk)
                    tran.Commit();
                else
                {
                    tran.Rollback();
                }
            }
            catch (Exception)
            {
                tran.Rollback();
            }
        }
    }
}

That seems to work, but how can I unit-test it?

UserManager<> constructor accepts IUserStore<>, so I can easily stub it.

UserStore<> constructor accepts DbContext, no idea how I can stub this.


回答1:


You can implement your own test user store that can be stubbed out for your unit test.

If you want to use the actual EF UserStore in your tests, that also will work, but it will be creating a database using the DefaultConnection string by default. You could specify a DatabaseInitializer to always drop/recreate your tables in your tests if you wanted to ensure a clean db for every test.



来源:https://stackoverflow.com/questions/19385043/what-is-the-recommended-way-to-run-asp-net-identity-functions-in-transaction

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!