Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体中的服务行为-如何避免向实体中注入服务?_C#_Nhibernate_Dependency Injection_Dns_Domain Driven Design - Fatal编程技术网

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

C# 实体中的服务行为-如何避免向实体中注入服务?,c#,nhibernate,dependency-injection,dns,domain-driven-design,C#,Nhibernate,Dependency Injection,Dns,Domain Driven Design,我的实体结构如下: IManager: IDeletable { IEnumerable<IFund> Funds {get;} IFailureNotification Delete(); } IFund : IDeletable { IEnumerable<IFundClass> FundClasses IFailureNotification Delete(); } IFundClass: IDeletable, IInvestable { IFailureNo

我的实体结构如下:

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

IFund : IDeletable
{
IEnumerable<IFundClass> FundClasses
IFailureNotification Delete();
}

IFundClass: IDeletable, IInvestable
{
IFailureNotification Delete();
}
IManager:IDeletable
{
IEnumerable Funds{get;}
IFailureNotification Delete();
}
IFund:理想的
{
IEnumerable基本类
IFailureNotification Delete();
}
IFundClass:可理想、不可投资
{
IFailureNotification Delete();
}
我有一个服务,它接受一个
IDeletable
并调用Delete。然后根据返回值提交事务或回滚事务。我使用NHibernate来持久化类,因此无法将RI放入DB中并捕获异常(无论如何我都不喜欢)

这是多态性的典型案例,
Manager
循环通过其
基金
并在删除自身之前删除它们,
Fund
依次在删除自身之前删除
FundClass
es,因此,该服务只需接收实现
IDeletable
的任何实体,并知道删除操作将在所有级别执行适当的操作

问题是:基金类需要通过
IInvestable
接口来确定它们是否在完全独立的环境中使用,而这些接口他们对这些情况一无所知。这需要一项服务——
IInvestmentCalculationService


显然,我不想将
InvestmentCalculationService
注入基金类实体构造函数,也不想将其注入delete方法,因为这是针对基金和经理以及许多其他类的,因此没有任何意义-也意味着一旦我们有更多的需求,我们就必须更改delete方法什么都有办法

我对这里的域事件模型有点感兴趣:但我不相信它是正确的,因为我正在尝试从触发事件处理程序获取数据-这会起作用,但闻起来有点错误,所有的示例都只显示了火灾和遗忘情况


有人有什么建议吗?

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

“显然,我不想注入
投资计算服务。”

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

我个人认为将服务注入实体是很好的,并且认为您应该停止担心它,而是去做。也许不需要注入整个InvestmentCalculationService,但如果您觉得实体不需要访问整个服务,则可以注入InestmentCalculationService中的BitsofInvestmentCalculationService

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


只需将InvestmentCalculationService注入实体并开始您的生活。

拥有一个界面如何

public interface ICanBeDeleted<T>
{
    bool CanBeDeleted(T itemToBeDeleted);
}
公共接口已删除
{
bool可删除(T项待删除);
}

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

感谢所有人的帮助,我吸引的观众给我留下了深刻的印象!我特别喜欢麦金太尔的哲学,从那时起它就真正影响了我的思想。在这种情况下,虽然我们采取了双重派遣。感觉稳定一点


干杯

嗨,吉米,我不确定这是如何解决问题的。第二个删除服务如何知道检查是否投资了
FundClass
?这不是以if(x是IFundClass)然后_fundClassChecker.check(x)?今天早上我想到的一个可能的解决方案是在Delete方法中插入
IDeletionValidationFactory
。然后,fund类可以调用
GetFundClassDeletionValidator
,并使用此检查确认可以删除。对我来说,这感觉像是双重分派的一个稍微抽象的版本。你觉得这个怎么样?感谢您的关注。您所说的“只需将InvestmentCalculationService注入实体”,是指通过构造函数注入,还是作为Delete方法中的一个参数?使用构造函数,如果将其置于Delete方法中,调用方需要了解InvestmentCalculationService,这破坏了封装。接下来的问题,通常这可以正常工作,除了例如,当我从数据库加载实体时,如果数据库中有1000行,这是否意味着对于这1000条记录,我必须将这些依赖项注入每个实体,即使我不需要调用delete方法?,例如,当我想列出网页上的所有行时。如果加载10000条记录,则ctor参数的成本将可以忽略不计。成本将是对实体进行反序列化和水合,这将涉及创建、使用和丢弃许多其他对象。如果愿意,您还可以注入factory Func而不是InvestmentCalculationService,并且由于某些原因,创建该服务的成本很高。