我正在开发ASP.NET MVC 4 application + NHibernate/Fluent NHibernate + Ninject
应用程序。
我已经创建了一个单独的模块来解决下面ISession
和ISessionFactory
的依赖关系,
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>()));
在第一次请求时一切正常,但是从第二次请求我得到了
会话已关闭错误
。有什么建议吗?
答案 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
创建自己的工厂