C# 具有NHibernate、Ninject和Windows窗体的3层体系结构 p>所以我正处于一个由NHiBiite访问的SQLite数据库支持的小到中等大小的Windows窗体应用程序的中间。当前的解决方案只包含一个App项目和Lib项目,因此在许多地方它的结构不是很好,并且紧密耦合
我开始时的结构类似于,但后来遇到了一些问题C# 具有NHibernate、Ninject和Windows窗体的3层体系结构 p>所以我正处于一个由NHiBiite访问的SQLite数据库支持的小到中等大小的Windows窗体应用程序的中间。当前的解决方案只包含一个App项目和Lib项目,因此在许多地方它的结构不是很好,并且紧密耦合,c#,winforms,nhibernate,dependency-injection,ninject,C#,Winforms,Nhibernate,Dependency Injection,Ninject,我开始时的结构类似于,但后来遇到了一些问题 DB初始化: 由于构建NHibernate SessionFactory的代码位于DAL中,我需要将ISession注入我的存储库,因此我需要直接在表单项目中引用DAL和NHibernate,以便能够使用Ninject设置DI(这应该在应用程序项目/表示层中完成,对吗?) 对于这样的架构,这不是我试图避免的事情之一吗 在理想世界中,哪些项目应该相互参照 DI一般情况下: 我很难弄清楚如何正确地进行DI。我读过关于使用复合根目录只在一个地方直接使用Nin
MainForm
,它显然是应用程序的入口点,在其整个生命周期中保持一个会话。此外,用户还可以打开多个子表单(主要但不限于)以编辑单个实体),每个子表单当前都有一个单独的会话,且生命周期较短。这是通过一个静态助手公开SessionFactory并根据需要打开新会话来完成的存储库
和服务
,我有点困惑。在发布的回答中有一条评论说“存储库包含业务逻辑是可以的,在这种情况下,您可以称之为服务”。当我们经常想将过滤等推送到数据库中时,我们的存储库只包含基本的CRUD操作,这让人觉得有些无用。因此,我们继续使用GetByName
或更复杂的GetAssignmentCandidates
等方法扩展存储库。这感觉很合适,因为实现在业务层,但它们仍然被称为存储库。对于直接与UI元素交互的类,我们使用了控制器
,但我认为这个名称在Web世界中更为常见存储库
真的应该被称为服务
对不起,这是文字墙。任何答案都将不胜感激 关于1:
是和否。是的,您希望UI层不依赖于x层的某些细节。但事实并非如此。合成根只是驻留在同一个程序集中,逻辑上它不是同一层
关于2:
限制容器的使用。工厂(对于会话,…)有时是必要的。应避免使用静态
。然而,有些框架阻止您使用理想的设计。在这种情况下,请尽可能接近。
如果您当前可以执行new FooForm()
,那么您可以用DI或DI工厂(p.Ex.)来替换它。如果您完全无法控制类型实例化的方式,那么您需要使用static
像服务定位器一样访问内核,然后“定位”直接依赖项(而间接依赖项由DI容器注入直接依赖项)
关于3:我认为这有点争议,可能经常被误解。我不认为你所称的类真的那么重要(当然是这样,但是代码库的一致性比决定是否将它们全部命名为存储库或服务更重要),重要的是你如何设计它们的责任和关系。
因此,我自己更喜欢在
-Query
命名类中提取过滤器和内容,每个类只提供一个方法。但其他人有其他偏好。。。我认为已经有足够多的关于这个主题的博客帖子等,在这里重新讨论是没有用的。针对像您这样的情况实施的最佳实践是使用MVP设计模式。这就是我可以提供给你的架构
- EntityBase.cs
- businesrule.cs
- 电子商务
- IRepository.cs
- Category.cs//实现Entityity并从EntityBase派生
- ICategoryRepository.cs//实现IRepository
- IHomeView.cs//放置所需的所有属性和方法
- ICategoryPresenter.cs
- CategoryPresenter.cs//Implements ICategoryPresenter CategoryPresenter(IHomeView视图,iCategoryService类别设备){ }
Page_Init(){
// Get instance of Presenter
var categoryPresenter = CategoryPresenter(this, new CategorySevice);
}