c# - 减少对 SignalR、NHibernate 和 Ninject 的依赖

标签 c# nhibernate dependency-injection signalr

一个架构问题。我有一个很好解耦的 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 设置为基础设施项目中每个请求的 session ,因此 Proj.Web 不需要引用 NHibernate(或 Ninject)。我现在介绍 SignalR,它非常适合快速聊天应用程序。我在网络项目中放置了一个 SignalR 集线器。我现在想将聊天消息持久化到数据库中,这让我有些困惑。

我想使用一个服务(我们称之为 PostService),因此 SignalR 中心不依赖于 NHibernate。我的其他服务被注入(inject)到 Controller 的构造函数中,并且 session 被注入(inject)到服务的构造函数中。

由于 SignalR 集线器挂起,与 Controller 不同,PostService(作为 IPostService 注入(inject)到构造函数中)无法将 session 注入(inject)到其构造函数中,因为不会是一个 session 。如果有的话,它会永远徘徊,这对于事务来说太长了。

我可以将 session 工厂注入(inject)到 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 方法执行更多操作,我将希望使用一些现有的服务来执行这些操作,因为它们已经编写并经过单元测试。由于 session 是在方法中创建的,因此我无法将服务注入(inject)到 PostService 构造函数中,因为它们将 session 接受到其构造函数中。

所以,我想我有以下选项,但我不确定 a) 这是一个完整的列表,还是 b) 哪个是最佳选项:

我。将 IDependencyResolver 注入(inject)到 PostService 构造函数中,并在 Post 方法中创建我需要的服务,并将 session 传递给构造函数。 System.Web.Mvc 和 SignalR 中有一个 IDependencyResolver,因此这会(取决于 PostService 所在的项目)引入对任一库的依赖关系。

二.修改服务,以便每个使用 session 的方法都有一个作为参数传入。在没有 session 参数的情况下重载它,并调用新的。 MVC 服务调用将使用第一个,PostService 将使用第二个,例如

public void SaveUser(IUser user) 
{
    Save(_session, user);
}

public void SaveUser(ISession session, IUser user) 
{
    session.Save(user);
}

三.不要使用现有的服务。让 PostService 做自己的事情,即使有一些重复(例如获取用户详细信息等)

四。从服务的构造函数中删除 ISession,并将其传递给每个方法(并相应地处理 Controller

V.还有别的事。

我想我倾向于第一个,但我不确定 PostService 将位于哪里。如果它进入 Proj.Services.NH,那么我必须引入对 System.Web.Mvc 或 SignalR 的依赖,但我不想这样做。如果它存在于 Proj.Web 中,那么我必须引入对 NHibernate 的依赖,但我也不想这样做。它不属于 Proj.Infrastruct,因为它是应用程序代码。它应该拥有自己的项目并依赖于所有内容,还是有更好的方法?

最佳答案

我会使用某种汽车工厂来提供您需要的附加服务。因此,您可以将 PostService 构造函数编写为:

public PostService( Func<INeededService1> factory1,Func<INeededService2> factory2 ...)
{
...
}

然后使用 this extension让这些工厂自动工作(通过查询容器)。

关于c# - 减少对 SignalR、NHibernate 和 Ninject 的依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11012612/

相关文章:

c# - $SpecificSolutionName$ 始终为空。我如何判断用户是否正在创建新的解决方案目录?

c# - 如何在 MySQL 服务器和 Microsoft SQL Server 2008 中使用 NHibernate

asp.net-mvc - asp.net mvc 4 - 可以为每个线程共享 DbContext 吗?

c# - Dummies 的控制反转(IoC/依赖注入(inject))

nhibernate - 如何映射具有IList值的IDictionary?

php - PHP 中的依赖注入(inject)

c# - 如何对 TextBox.Triggers(事件触发器)执行某些操作?

c# - 使用 SQL 更新 250k 行的更快方法

c# - 使用 DataGridViewCheckboxCell 真正禁用 DataGridView 中的复选框

c# - NHibernate 映射属性 + 脏检查