为什么HttpContext在Controller的构造函数中是空的?

时间:2016-06-01 17:53:43

标签: c# asp.net-mvc httpcontext

Startup.Auth.cs //我在这里添加了我的DbContext

// Configure the db context, user manager and signin manager to use a single instance per request
app.CreatePerOwinContext(ProjectPlannerContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

AccountController.cs 中,我想创建一个服务实例,需要 UnitOfWork 实例来执行数据库相关的操作。所以这是代码:

public AccountController()
{
    contactManager = new ContactManager(UnitOfWork);
}

其中 UnitOfWork 是这样定义的属性:

public UnitOfWork UnitOfWork
{
    get
    {
        if (unitOfWork == null)
        {
            //Here the HttpContext is NULL
            unitOfWork = new UnitOfWork(HttpContext.GetOwinContext().Get<ProjectPlannerContext>());
        }

        return unitOfWork;
    }
}

我应用了一个全局授权过滤器,所以当我运行应用程序时,首先要做的是登录到网站(这将导致对AccountController的登录方法的请求 - 并给出一个错误对象引用而不是设置为实例,因为在控制器构造函数中调用了UnitOfWork。

对我来说奇怪的是,如果我在构造函数中注释contactManager行,则在登录时Asp.NET MVC使用如下定义的 SignInManager

public ApplicationSignInManager SignInManager
{
    get
    {
        return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
    }
    private set 
    { 
       _signInManager = value; 
    }
}

这完全有效,我可以注册(对象引用错误不会抛出),并在数据库中看到我的用户被插入。 所以我的问题是为什么会发生这种情况,以及如果不在构造函数中如何初始化我的服务?

如果我定义 UnitOfWork ,实际上有解决方法:

public UnitOfWork UnitOfWork
{
    get
    {
       if (unitOfWork == null)
       {
           unitOfWork = new UnitOfWork(ProjectPlannerContext.Create());
       }

       return unitOfWork;
    }
}

但这意味着我应该在每个Controller中创建数据库上下文..

最佳做法/解决方案是什么?

1 个答案:

答案 0 :(得分:2)

我最终实现了将从其他控制器派生的BaseController,这里是示例:

public abstract class BaseController : Controller
{
    public virtual UnitOfWork UnitOfWork
    {
        get
        {
            return unitOfWork;
        }
    }

    protected override void Initialize(RequestContext requestContext)
    {
        base.Initialize(requestContext);

        if (unitOfWork == null)
        {
            unitOfWork = new UnitOfWork(HttpContext.GetOwinContext().Get<ProjectPlannerContext>());
        }
    }

    #region Private members
    private UnitOfWork unitOfWork;
    #endregion
}

需要额外服务的AccountController(IContactManager):

public class AccountController : BaseController
{
    public AccountController()
    {

    }

    protected override void Initialize(RequestContext requestContext)
    {
        base.Initialize(requestContext);

        contactManager = new ContactManager(UnitOfWork);
    }

    public ActionResult CreateContact(string firstName, string lastName, string email)
    {
        ContactModel contact = contactManager.Create(firstName, lastName, email);

        return JsonNet(new { contact = contact });
    }

    #region Private members
    private IContactManager contactManager;
    #endregion
}