一个建筑问题。我有一个很好的解耦 MVC3 解决方案,其中一些项目运行良好。
Proj.Core - interfaces for data classes and services Proj.Services - interfaces for model services Proj.Data.NH - implementations of the data interfaces Proj.Services.NH - implementations of the data / model services Proj.Infrastructure - setting up Ninject and NHibernate Proj.Tests - unit tests Proj.Web - the MVC project
我已经将 NHibernate 设置为基础结构项目中的每个请求的会话,因此 Proj.Web 不需要引用 NHibernate(或 Ninject,就此而言)。我现在介绍 SignalR,它非常适合用于快速聊天应用程序。我在 Web 项目中放置了一个 SignalR 集线器。我现在想将聊天消息保存在数据库中,这让我有些困惑。
我想使用一项服务(我们称之为PostService
),因此 SignalR 集线器不依赖于 NHibernate。我的其他服务被注入到控制器的构造函数中,会话被注入到服务的构造函数中。
由于 SignalR 集线器挂起,与控制器不同,PostService
(作为 注入到构造函数中IPostService
)不能将会话注入到其构造函数中,因为不会有会话。如果有,它将永远存在,这对于交易来说时间太长了。
我可以将会话工厂注入到 中PostService
,并且每个方法都可以使用事务,例如
private void WithTransaction(Action<ISession> action)
{
using (var session = _sessionFactory.OpenSession())
using (var tx = session.BeginTransaction())
{
action(session);
tx.Commit();
}
}
public IPost Post(string message)
{
WithTransaction(session =>
{
session.Save(new Post(message));
});
}
然后集线器将调用_postService.Post(message);
但是,一旦该Post
方法做了更多的事情,我会想使用我现有的一些服务来做这些事情,因为它们已经被编写和单元测试过。由于会话是在方法中创建的,因此我无法将服务注入PostService
构造函数,因为它们接受会话进入其构造函数。
所以,我想我有以下选择,但我不确定 a)这是一个完整的列表,还是 b)这是最好的选择:
IDependencyResolver
一、在构造函数中注入an PostService
,在方法中创建自己需要的服务Post
,将session传入构造函数。System.Web.Mvc 和 SignalR 中有一个IDependencyResolver
,因此这将(取决于PostService
所在的项目)引入对任一库的依赖。
二、修改服务,使每个使用会话的方法都有一个作为参数传入。在没有 session 参数的情况下重载它,然后调用新的。MVC 服务调用将使用第一个,并且PostService
将使用第二个,例如
public void SaveUser(IUser user)
{
Save(_session, user);
}
public void SaveUser(ISession session, IUser user)
{
session.Save(user);
}
三、不要使用现有的服务。做PostService
自己的事,即使有一些重复(例如获取用户详细信息等)
四。从服务的构造函数中删除 ISession,并将其传递给每个方法(并相应地处理Controller
s'。
V. 别的东西。
我想我倾向于第一个,但我不确定PostService
住在哪里。如果它进入 Proj.Services.NH,那么我将不得不引入对 System.Web.Mvc 或 SignalR 的依赖,这是我不想做的。如果它存在于 Proj.Web 中,那么我将不得不引入对 NHibernate 的依赖,我也不想这样做。它不属于 Proj.Infrastructure,因为它是应用程序代码。它应该有自己的项目,依赖于所有东西,还是有更好的方法?