【问题标题】:NInject, NHIbernate and ISession in request scope请求范围内的 NInject、NHIbernate 和 ISession
【发布时间】:2014-07-24 13:57:43
【问题描述】:

我基本上使用了一个我在很多地方都见过的例子,但我不相信它可以正常工作。

所以,我有以下内容:

public class NHibernateHelper
{
    private readonly string _connectionString;
    private ISessionFactory _sessionFactory;

    public ISessionFactory SessionFactory
    {
        get { return _sessionFactory ?? (_sessionFactory = CreateSessionFactory()); }
    }

    public NHibernateHelper(string connectionString)
    {
        _connectionString = connectionString;
    }

    private ISessionFactory CreateSessionFactory()
    {
        return Fluently.Configure()
                .Database(FluentNHibernate.Cfg.Db.MySQLConfiguration.Standard
                    .Dialect("NHibernate.Spatial.Dialect.MySQLSpatialDialect,NHibernate.Spatial.MySQL")
                    .ConnectionString(_connectionString))
                    .Mappings(m => m.FluentMappings.AddFromAssemblyOf<EventListing>())
                    .ExposeConfiguration(x =>
                    {
                        x.SetProperty(NHibernate.Cfg.Environment.CurrentSessionContextClass, ConfigurationManager.AppSettings["current_session_context_class"]);
                    })
                .BuildSessionFactory();
    }
}

在我的 Ninject 启动中我有

private static void RegisterServices(IKernel kernel)
    {
        NHibernateHelper helper = new NHibernateHelper(WebConfigurationManager.ConnectionStrings["eventlisting"].ConnectionString);
        kernel.Bind<ISessionFactory>().ToConstant(helper.SessionFactory).InSingletonScope();
        kernel.Bind<ISession>().ToProvider(new SessionProvider()).InRequestScope();
        kernel.Bind(typeof(IReadOnlyRepository<>)).To(typeof(ReadOnlyRepository<>)).InRequestScope();
        kernel.Bind(typeof(IRepository<>)).To(typeof(Repository<>)).InRequestScope();
}

我的会话提供者类看起来像

public class SessionProvider : Provider<ISession>
{
    protected override ISession CreateInstance(IContext context)
    {
        ISession session = DependencyResolver.Current.GetService<ISessionFactory>().OpenSession();
        session.FlushMode = FlushMode.Auto;
        return session;
    }
}

令我困惑的是,尽管声明应该在请求范围内创建 ISession,但它似乎在每个请求中多次点击 CreateInstance 方法,并且看起来正在产生多个会话。

例如如果我有一个带有这个构造函数的控制器:

public SomeController(
        IRepository<SomeClass> someClassRepository,
        IRepository<SomeOtherClass> someOtherClassRepository)
    {
        _someClassRepository = someClassRepository;
        _someOtherRepository = someOtherClassRepository;
    }

然后 CreateInstance 方法被调用两次(我应该为存储库添加构造函数,需要一个 ISession 参数):

public Repository(ISession session)
    {
        this.Session = session;
    }

我认为将它作为 InRequestScope 意味着它只被调用一次。是我误会还是我在某处遗漏了一些代码。

【问题讨论】:

    标签: c# nhibernate ninject isession


    【解决方案1】:

    我做了一个快速测试来验证 ninject 的“基本”范围和提供程序功能是否正常工作:

    public class StringProvider : Provider<string>
    {
        protected override string CreateInstance(IContext context)
        {
            return context.ToString();
        }
    }
    
    
    var kernel = new StandardKernel();
    
    kernel.Bind<string>().ToProvider(new StringProvider()).InSingletonScope();
    
    kernel.Get<string>();
    kernel.Get<string>();
    kernel.Get<string>();
    

    在这种情况下,StringProvider.CreateInstance(..) - 正确 - 只被调用一次。


    我相信您的问题在于提供 .InRequestScope() 的 ninject 扩展的正确配置。可悲的事实是,当它没有正确配置时,它不会对你大喊大叫/抛出异常,不,它会保持安静。只有当意外的行为让你大吃一惊时,你才会发现它;-)

    请看这里:ASP.NET MVC + Ninject: InRequestScope 这是我昨天刚刚回答的此类问题的一个实例。

    【讨论】:

      猜你喜欢
      • 2015-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多