1

我正在开发一个 ASP.NET MVC 应用程序,我在其中使用 NHibernate 和 Ninject。

问题是由以下控制器引起的:

public class ShoppingCartController : Controller
{
    private readonly Data.Infrastructure.IShoppingCartRepository _shoppingCartRepository;
    private readonly Data.Infrastructure.IShopItemRepository _shopItemRepository;

    public ShoppingCartController(Data.Infrastructure.IShoppingCartRepository shoppingCartController, 
        Data.Infrastructure.IShopItemRepository shopItemRepository)
    {
        _shoppingCartRepository = shoppingCartController;
        _shopItemRepository = shopItemRepository;
    }

    public ActionResult AddToShoppingCart(FormCollection formCollection)
    {
        var cartItem = new Data.Models.ShoppingCartItem();
        cartItem.ChangeDate = DateTime.Now;
        cartItem.ShopItem = _shopItemRepository.GetShopItem(SessionData.Data.Info, Convert.ToInt32(formCollection["shopItemId"]));
        //IF I DONT´T CALL THE METHOD ABOVE, AddToCart works

        _shoppingCartRepository.AddToCart(SessionData.Data.Info, cartItem);
        //BUT IF I CALL THE GetShopItem METHOD I GET THE EXCEPTION HERE!
        return RedirectToAction("Index", "Shop");
    }
}

我知道大多数时候这个异常是由错误的映射引起的,但我很确定我的映射是正确的,因为如果我不调用 GetShopItem,AddToCart 方法就可以工作......

所以这里是 ShopItemRepository 的代码:

public class ShopItemRepository : ReadOnlyRepository<ShopItem>, IShopItemRepository
{
    public ShopItemRepository(IUnitOfWork uow) : base(uow)
    {

    }

    public ShopItem GetShopItem(SessionParams param, int id)
    {
        return CurrentSession.QueryOver<ShopItem>()
                       .Where(x => x.ProcessId == param.ProcessId && 
                                   x.CatalogueId == param.CatalogueId && 
                                   x.Id == id)
                       .SingleOrDefault();
    }

    public IList<ShopItem> GetShopItems(SessionParams param)
    {
        return CurrentSession.GetNamedQuery("GetShopItems")
                       .SetParameter("requestor_id", param.RequestorId)
                       .SetParameter("recipient_id", param.RecipientId)
                       .SetParameter("process_id", param.ProcessId)
                       .SetParameter("catalogue_id", param.CatalogueId)
                       .List<ShopItem>();
    }
}

最后是我的 UnitOfWork 的代码(基本上它只是 Session 的包装器,因为我不想在我的 MVC 项目中引用 NHibernate)

public class UnitOfWork : IUnitOfWork, IDisposable
{
    private NHibernate.ISession _currentSession;
    public NHibernate.ISession CurrentSession
    {
        get
        {
            if(_currentSession == null)
            {
                _currentSession = SessionFactoryWrapper.SessionFactory.OpenSession();
            }
            return _currentSession;
        }
    }

    public void Dispose()
    {
        if(_currentSession != null)
        {
            _currentSession.Close();
            _currentSession.Dispose();
            _currentSession = null;
        }
        GC.SuppressFinalize(this);
    }
}

附录:
我的 NinjectWebCommon 类

public static class NinjectWebCommon 
{
    private static readonly Bootstrapper bootstrapper = new Bootstrapper();

    /// <summary>
    /// Starts the application
    /// </summary>
    public static void Start() 
    {
        DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
        DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
        bootstrapper.Initialize(CreateKernel);
    }

    /// <summary>
    /// Stops the application.
    /// </summary>
    public static void Stop()
    {
        bootstrapper.ShutDown();
    }

    /// <summary>
    /// Creates the kernel that will manage your application.
    /// </summary>
    /// <returns>The created kernel.</returns>
    private static IKernel CreateKernel()
    {
        var kernel = new StandardKernel();
        kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
        kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();

        RegisterServices(kernel);
        return kernel;
    }

    /// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();

        kernel.Bind<Data.Infrastructure.ICatalogueRepository>().To<Data.Repositories.CatalogueRepository>();
        kernel.Bind<Data.Infrastructure.ICategoryRepository>().To<Data.Repositories.CategoryRepository>();
        kernel.Bind<Data.Infrastructure.IContactRepository>().To<Data.Repositories.ContactRepository>();
        kernel.Bind<Data.Infrastructure.IProcessRepository>().To<Data.Repositories.ProcessRepository>();
        kernel.Bind<Data.Infrastructure.IShopItemRepository>().To<Data.Repositories.ShopItemRepository>();
        kernel.Bind<Data.Infrastructure.IShoppingCartRepository>().To<Data.Repositories.ShoppingCartRepository>();
    }        
}

IUnitOfWork 设置为 RequestScope 因此在 ShoppingCartController 的情况下,两个存储库共享相同的 UOW 对吗?

也许这可能会导致问题?

4

1 回答 1

1

你确定这不是由错误的映射引起的吗?我有同样的问题,可以通过再次检查我的映射来解决它!

于 2013-11-12T16:54:34.013 回答