解决模型绑定器中的依赖关系的问题

时间:2013-01-25 06:43:53

标签: asp.net-mvc nhibernate fluent-nhibernate ninject

我正在开发ASP.NET MVC 4 application + NHibernate/Fluent NHibernate + Ninject应用程序。

我已经创建了一个单独的模块来解决下面ISessionISessionFactory的依赖关系,

  public class RepositoryModule: NinjectModule
  {
    public override void Load()
    {
      Bind<ISessionFactory>()
        .ToMethod(e => Fluently.Configure()
        .Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("DbConnString")))
        .Cache(c => c.UseQueryCache().ProviderClass<HashtableCacheProvider>())
        .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Post>())            
        .BuildConfiguration()
        .BuildSessionFactory())
        .InSingletonScope();

      Bind<ISession>()
        .ToMethod((ctx) => ctx.Kernel.Get<ISessionFactory>().OpenSession())
        .InRequestScope();
    }
  }

我有一个实现BlogRepository的存储库类IBlogRepository

  public class BlogRepository : IBlogRepository
  {
    private readonly ISession _session;

    public BlogRepository(ISession session)
    {
      _session = session;
    }

    public IList<Post> Posts(int pageNo, int pageSize)
    {
      var query = _session.Query<Post>()
                          .Where(p => p.Published)
                          .OrderByDescending(p => p.PostedOn)
                          .Skip(pageNo * pageSize)
                          .Take(pageSize)
                          .Fetch(p => p.Category);

      query.FetchMany(p => p.Tags).ToFuture();

      return query.ToFuture().ToList();
    }

    // others
  }

我需要在自定义模型绑定器中使用BlogRepository的实例。

我在Global.asax.cs中尝试过类似的东西。

ModelBinders.Binders.Add(typeof(Post), new PostModelBinder(Kernel.Get<IBlogRepository>()));

在第一次请求时一切正常,但是从第二次请求我得到了

  

会话已关闭错误

。有什么建议吗?

1 个答案:

答案 0 :(得分:1)

这是因为ModelBinder的生命周期比一个请求长。如您所见,您正在使用PostModelBinder运算符注册new。 MVC应用程序保留对此绑定程序的引用,绑定程序引用IBlogRepository,其ISession将在第一个请求的末尾处理。

您可以使用工厂

解决此问题

您将注入工厂IBlogRepository对象,而不是IBlogRepositoryFactory,而是在每次IBlogRepository来电时创建新的BindModel

要完成此操作,您可以使用Ninject factory extension

或者按照接受的答案Inject a dependency into a custom model binder and using InRequestScope using Ninject

创建自己的工厂