【问题标题】:Reducing dependencies with SignalR, NHibernate and Ninject使用 SignalR、NHibernate 和 Ninject 减少依赖关系
【发布时间】:2012-06-13 10:06:06
【问题描述】:

一个架构问题。我有一个很好的解耦 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 注入PostService 构造函数,并在Post 方法中创建我需要的服务,将会话传递给构造函数。 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,并将其传递给每个方法(并相应地处理 Controllers'。

V。别的东西。

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

【问题讨论】:

    标签: c# nhibernate dependency-injection signalr


    【解决方案1】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-09
      • 1970-01-01
      • 1970-01-01
      • 2015-10-16
      • 1970-01-01
      • 1970-01-01
      • 2016-11-29
      相关资源
      最近更新 更多