C# 我的表示层是否应该在NHibernate中创建会话?

C# 我的表示层是否应该在NHibernate中创建会话?,c#,wpf,nhibernate,C#,Wpf,Nhibernate,我正在学习NHibernate,并创建了一些单元测试,进展非常顺利。我的主应用程序只有两层: 演示文稿(WPF应用程序) 域(具有业务逻辑和数据访问权限) 当然,我有我的单元测试项目(test) 我的单元测试在[TestFixtureSetup]期间调用我的SessionManager类来构建一个SessionFactory。然后,每个[Test]获取一个会话来执行数据访问单元测试。我想知道我应该如何在我的WPF项目中做到这一点 我创建了一个简单的对话框,看看是否可以将WPF应用程序连接到数据库

我正在学习NHibernate,并创建了一些单元测试,进展非常顺利。我的主应用程序只有两层:

  • 演示文稿(WPF应用程序)
  • 域(具有业务逻辑和数据访问权限)
  • 当然,我有我的单元测试项目(test)

    我的单元测试在
    [TestFixtureSetup]
    期间调用我的
    SessionManager
    类来构建一个
    SessionFactory
    。然后,每个
    [Test]
    获取一个
    会话来执行数据访问单元测试。我想知道我应该如何在我的WPF项目中做到这一点

    我创建了一个简单的对话框,看看是否可以将WPF应用程序连接到数据库。在我的演示层中引用NHibernate是不对的,我的这种感觉对吗?如果是这样,当用户在我的表单上单击
    Add
    来存储某个对象时,我应该如何获得一个会话来存储该对象?以下是我的一些代码:

    public class SessionManager
    {
        private ISessionFactory _sessionFactory;
    
        public SessionManager()
        {
            _sessionFactory = GetSessionFactory();
        }
    
        public ISession GetSession()
        {
            return _sessionFactory.OpenSession();
        }
    
        private ISessionFactory GetSessionFactory()
        {
            return (new Configuration()).Configure().BuildSessionFactory();
        }
    }
    
    在我的测试项目中,我有这样的东西:

        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {
            log4net.Config.XmlConfigurator.Configure();
            DatabaseFixtureSetUp();
            _sessionManager = new SessionManager();
        }
    
        [SetUp]
        public void Setup()
        {
            DatabaseSetUp();
    
            _session = _sessionManager.GetSession();
        }
    
    我不知道如何构造表示层代码来存储对象。我的表格上有:

        private void btnAddBroker_Click(object sender, RoutedEventArgs e)
        {
            var broker = new Broker
            {
                Name = txtBrokerName.Text,
                IsActive = (bool)chkIsActive.IsChecked,
                IsDefault = (bool)chkIsDefault.IsChecked
            };
    
            // save the broker object to the database
            // is it ok to have NHibernate code here? feels wrong
    
        }
    

    你会怎么做?

    虽然我不是WPF应用程序方面的专家,但我来自Web开发,我会说是的,表示层生成会话确实感觉不对

    我的建议是创建一个负责创建NHibernate会话的工厂类(我看到您是使用SessionManager创建的)。然后,您的业务层可以调用工厂类来获取NHibernate会话,然后在业务层中使用它来处理需要满足的任何请求

    然后,如果您坚持的话,您甚至可以使用和注入工厂类和业务层

    我相信你已经知道这一点,但我还是要提一下: 无论您决定如何拆分,目标都是将用户界面操作代码保留在一个层中,将业务代码保留在另一个层中,这样,如果您需要将此应用程序移植到Web应用程序,则可以重用业务层,并且只需开发表示层


    鉴于您已经在进行单元测试,首先编写单元测试将迫使您自然而然地考虑将类的责任划分为可单元测试的类,这是一件非常好的事情。我相信你走的是正确的道路。

    回答得好,谢谢。那么,将NHibernate会话引入表示层并从那里引用NHibernate库就可以了?我想知道我是否应该做一些类似于
    DAL.Repository.Save(broker)的事情或其他,然后Repository类创建会话等。但是SessionFactory的创建成本很高。。。我还不清楚,我在脑子里转来转去。你知道互联网上有什么例子可以说明我在做什么吗?我发现例子更清楚。嗯..不,我会制作一个单独的程序集,叫做类似业务层的东西。在业务层中,我将创建一个名为BrokerService之类的类。代理服务将依赖于SessionManager。BrokerService可以有一个名为AddBroker的方法,您可以将代理信息传递给该方法,然后该方法使用SessionManager创建一个Hybernate会话,用于将代理实体对象持久化到数据库。我找不到示例,但我建议您阅读DDD(域驱动设计)还有IOC控制反转感谢我现在开始阅读Head-First设计模式来帮助我了解全局。另外,如果您已经在使用.Net,并且已经理解了讨论的设计概念,那么您可以利用库让您的生活更轻松。例如IOC依赖项注入部分的StructureMap或Ninject。一旦定义了框架的依赖关系,要求它为您构建一个对象的新实例(即使是具有复杂依赖关系层次结构的实例)是一个简单的过程,只需要一行代码。