【问题标题】:Where do I put interfaces and their implementation?我在哪里放置接口及其实现?
【发布时间】:2013-09-26 02:43:12
【问题描述】:

我有上面插图中的项目布局。

我想编写一个带有接口 ISessionManager 的“SesisonManager”,使用我的容器将其连接起来并将其注入我的服务层。 UI 和基础设施层是最外层,此时只有核心作为依赖项,据我所知,这是正确的方法。

我的 SessionManager 看起来像这样。

 public interface ISessionManager:IDisposable
{
    ISession GetSession();

}

public class SessionManager : ISessionManager
{
    private readonly ISessionFactory _sessionFactory;
    private readonly ILogger _logger;
    private ITransaction _transaction;
    private ISession _session;
    public SessionManager(ISessionFactory sessionFactory,ILogger logger)
    {
        _sessionFactory = sessionFactory;
        _logger = logger;
    }

    public void Dispose()
    {
        try
        {
            if (_session == null) return;
            if (_transaction == null || !_transaction.IsActive) return;
            _transaction.Commit();
            _transaction.Dispose();
        }
        catch (Exception exception)
        {
            if (_transaction != null)
            {
                _transaction.Rollback();
                _transaction.Dispose();
            }

            _logger.Error("Something bad just happend");
        }
        finally
        {
            if (_session != null) _session.Dispose();
        }
    }

    public ISession GetSession()
    {
        if (CurrentSessionContext.HasBind(_sessionFactory))
        {
            _session = CurrentSessionContext.Unbind(_sessionFactory);
        }
        else
        {
            _session = _sessionFactory.OpenSession();
            CurrentSessionContext.Bind(_session);
        }

        // Let's make sure we have a transaction 
        _transaction = _session.BeginTransaction(IsolationLevel.ReadCommitted);
        return _session;
    }
}

这将通过构造函数注入到服务中,当我需要 ISession 时,我只需调用 GetSession。当 SessionManager 被释放时,事务将被提交或回滚,具体取决于发生的情况。

除了我不知道将接口和实现存放在哪里之外,这一切都有效。它不应该留在基础设施中,因为服务层依赖于它并且它是上面的一层。 (根据洋葱标准,这很糟糕)。

我不能将接口放在 Core 中,因为我需要依赖 Nhibernate.. 所以不知道到底要在这里做什么。我正在考虑制作一个公共/共享层并让它充当中间人,但不确定这是正确的处理方式。

任何帮助将不胜感激。

【问题讨论】:

  • 我知道这不会让我在这里很受欢迎,但我有一个友好的建议——不要做“洋葱”架构,你会纠缠自己的抽象,你会后悔的。保持简单,以对您和您的团队有意义的方式分离您的组件。
  • 在这一点上,我感谢您对此事的看法。不过,我仍然想看看洋葱专家的建议。我没有“团队”,只有我自己。如果我确实有一个团队,与他们争论这样的事情会很有趣..正确的方法是什么.. :)
  • 我必须同意@DimitarDimitrov 我曾经被层层迷住并且总是以共同的项目结束。然后我学会了拥抱而不是抽象的 NHibernate。从那时起,我的生活变得更好了。
  • 我不知道 Onion 是什么,但我的 ISessionManager 接口始终驻留在系统的任何其他模块可见的公共项目中。但是presenter/controller被禁止引用NHibernate.dll,不能使用ISessionManager。
  • 我并不想将 Nhibernate 抽象出来。如果我想这样做,那么我会使用存储库。我只是或不那么简单地尝试降低依赖级别并拥有一个松散耦合的项目。

标签: c# asp.net-mvc-4 nhibernate onion-architecture


【解决方案1】:

在洋葱架构中,外层实现接口。

我的建议:设计您的域服务接口,以便在您的应用程序中方便地使用它们。在您的域服务实现中使用您的 ISessionManager。由于您的实现位于外层,因此您对 ISessionManager(以及因此 NHibernate)的依赖也在您的外层。

就我而言,我倾向于使用通用存储库而不是 NHibernate,但该决定仍然是我的域服务的实现细节。

如果我的域服务接口看起来像:

IWidgetService.MakeWidget(MakeWidgetParameters)

我的实现将打开一个 ISession 并完成我想要对 Db 进行的更改和持久化的工作。这样ISession就不会泄漏到外层了。

【讨论】:

    猜你喜欢
    • 2011-07-29
    • 2016-10-29
    • 1970-01-01
    • 1970-01-01
    • 2013-11-27
    • 1970-01-01
    • 2020-07-08
    • 1970-01-01
    • 2011-03-08
    相关资源
    最近更新 更多