代码之家  ›  专栏  ›  技术社区  ›  Stu

实体中的服务行为-如何避免向实体中注入服务?

  •  4
  • Stu  · 技术社区  · 15 年前

    我的实体结构如下:

    IManager: IDeletable
    {
    IEnumerable<IFund> Funds {get;}
    IFailureNotification Delete();
    }
    
    IFund : IDeletable
    {
    IEnumerable<IFundClass> FundClasses
    IFailureNotification Delete();
    }
    
    IFundClass: IDeletable, IInvestable
    {
    IFailureNotification Delete();
    }
    

    我有一项服务需要 IDeletable 并要求删除它。根据返回值,它要么提交事务,要么回滚事务。我正在使用nhibernate来持久化类,因此不能将ri放在db中并捕获异常(无论如何我都不喜欢)。

    这是多态性和 Manager 循环通过它 Funds 并在删除之前删除它们, Fund 依次删除 FundClass 在删除自己之前,这样服务就可以接受任何实现 有形的 并知道删除操作将在所有级别执行适当的操作。

    问题是:基金类需要使用 IInvestable 他们什么都不知道的界面。这需要一个服务- IInvestmentCalculationService .

    显然我不想注射 InvestmentCalculationService 在基金类实体构造函数中,我不想将其注入到删除方法中,因为这是对基金和经理以及许多其他类的,所以没有任何意义——也意味着一旦我们有了更多的要求,我们就必须更改所有内容的删除方法。

    我有点被这里的域事件模型所吸引: http://www.udidahan.com/2009/06/14/domain-events-salvation/ 但我不相信这是正确的,因为我正试图从触发的事件处理程序中获取数据——这会起作用,但有点错误,所有的示例只显示Fire和Forget情况。

    有人有什么建议吗?

    4 回复  |  直到 13 年前
        1
  •  2
  •   Stu    14 年前

    感谢大家的帮助,我对我吸引的观众印象深刻!我特别喜欢麦金太尔的哲学,它真正影响了我的思想。在这种情况下,尽管我们进行了双重派遣。感觉有点稳定。

    干杯

        2
  •  2
  •   Brock Adams    13 年前

    “显然,我不想注射 InvestmentCalculationService “。

    “显然”这个词我不喜欢。我仍然没有被谷歌“向实体注入服务”的结果所驱使。关于这个主题的最上面的帖子归结为“感觉不太对劲,你可以使用域事件/双调度来完成它,所以不要这样做”。

    我个人认为向实体注入服务并认为你应该停止担心它并做到这一点是好的。也许不需要注入整个InvestmentCalculationService,但是如果你觉得实体不需要访问整个服务,那么就注入那些不知道服务的InvestmentCalculationService的位。

    域事件在您的情况下是不好的,除非您添加一个返回值(这基本上使它成为一个修饰的服务定位器),并且通过双重分派,您所注入的东西必须来自调用堆栈更高的地方——可能是入口点类的一个注入值,很可能根本不使用这种依赖性。

    只需将InvestmentCalculationService注入实体并继续您的生活。

        3
  •  1
  •   Jimmy Bogard    15 年前

    在这种情况下,我们所做的一件事是让delete不执行实际的删除操作,而是使用collection参数来删除要删除的内容。delete()方法将注册自身和任何其他对象,然后由其他服务重播这些对象。

        4
  •  0
  •   Paul Linton    15 年前

    有接口如何

    public interface ICanBeDeleted<T>
    {
        bool CanBeDeleted(T itemToBeDeleted);
    }
    

    在实际删除之前,请向容器询问此接口的所有实现,调用 CanBeDeleted 函数,如果返回false,则不要删除。你的 InvestmentCalculationService 将实施 ICanBeDeleted<FundClass> 并在容器中登记。