规则“只存储在IoC容器中的服务,不存储任何实体”。我在blog中找到了它,它有很多支持者。
还有一些类构造函数的示例:
MyClass(ILog log,
IAudit audit,
IPermissions permissions,
IApplicationSettings settings) {/*..*/}其中MyClass被声明为不应存储在容器中的实体。
所以"IoC就绪服务“不能依赖于基础设施..服务。
但现在我完全不明白"IoC people“是如何使用”真正的代码“的。C#中的服务仍然将被开发为一个类,并且该类通常依赖于封装日志的类,很少依赖于封装自定义异常处理(例如,将未处理的异常转换为FaultContract)的类。
我看到了一些方法:可能他们只是不声明那些基础设施依赖?将它们用作静态方法中可用的功能?
或者,"IoC支持者“是否认为"IoC ready”服务应该将日志/跟踪/身份验证/handleException事件作为服务契约的一部分发布(然后是的--不存在“对基础设施的依赖”)?但这也意味着这样的服务应该是双工的(以发布日志事件)……
也许他们的“服务”只是代理?Proxy不依赖于基础架构,因为所有的基础架构都是远程的,但我并不乐于发现IoC容器只能用来存储代理。我的失望是对的吗?但是,MS Enterprise Library是如何设计的,它是为Unity容器中的记录器和处理程序而设计的呢?
追加:
我是这样理解的:有服务(有合同),有实体(业务),还有基础设施的东西LogWriter,AuthenticationProvider;-创建/托管服务我用一些基础设施的东西启动它(所以我发布的是对基础设施的依赖,而不是实体)。我还不明白的是,我说的对不对?
追加2:
经过讨论,我以这种方式理解了这种情况。ILog等-是服务(即使它们是基础设施服务),因此,如果"MyClass“是某个服务的实现,则不会违反规则。这意味着规则是好的,但样本是坏的。
剩下的一个问题:我仍然不能理解实体和服务在一句话中的对立,而没有解释。它们来自不同的概念层: 1)服务-消息;2)业务规则-实体。因此,可能首先我应该采用新的术语。
发布于 2011-08-24 12:56:40
简而言之:实体不应该依赖于服务!这是依赖倒置的“倒置”部分的很大一部分。正如你链接到的帖子中所述:
我发现问题示例的设计是错误的,从某种意义上说,实体( MyClass是)不应该依赖于基础设施(或任何其他)服务。
在您的示例中,MyClass依赖于三个横切关注点,外加IApplicationSettings。应该使用AOP/动态代理技术引入横切关注点,如果您愿意,也可以使用pubsub样式的事件。并且MyClass应该由负责创建其实例的任何服务注入特定于其功能的设置。例如,可以使用IApplicationSettings注入PersonFactory,然后创建Person对象,并将appSettings.SomePersonRelatedSetting传递给Person构造函数。
发布于 2011-08-24 12:43:27
规则“只存储在IoC容器中的服务,不存储任何实体”。意味着您应该在IoC容器对interace - implementation中注册。此规则是dependency inversion principle的结果。根据您的示例,这意味着您应该从MyClass中提取公共接口,并使用它而不是MyClass实现。
发布于 2011-08-24 12:45:31
规则是这样说的
"Store in IoC container only services. Do not store any entities."是从概念的角度,而不是从实现的角度。从概念上讲,实体表示数据(或状态),也可能表示与数据相关的规则(作为方法)。服务表示通过发布的契约公开的功能,通常情况下,全状态服务不是一个好主意。因此,尽管C# class结构将同时用于表示服务实现和实体实现-但这条规则说明的是,只有服务应该放入IoC中。IoC实际上充当了一个可配置的、超级灵活的工厂,它为所需的服务契约提供正确的服务实现。同样,可以有像ActiveRecord这样的模式,其中可能合并了数据和持久性功能-我本身不喜欢这种模式,但有很多追随者,典型的用法是将这些实体放入IoC容器中。然而,重要的区别可能是实体可能是根据某些合同注册的(而不是实现)
再次注意,您的代码依赖于服务契约,而不依赖于特定的服务实现。现在,可以通过多种方式公开和解决依赖关系。您可以通过将依赖项作为构造函数参数或公共属性getter/setter或使用声明性语法(如属性)来标记依赖项。这些问题通常由DI框架自动解决。但是,您始终可以通过显式调用来获取/解析某些服务,例如ILog log = DIContainer.Get<ILog>();。因此,就基础设施服务而言,我认为博客作者所说的是不要将基础设施服务标记为显式依赖(通过构造函数参数或属性等)。你可以使用代码(如上所述)或者使用简单的单例助手等来解决它们。在某种程度上,他是对的,因为人们总是可以假设每个服务/类都依赖于基础架构,因此不需要使用公共API来声明依赖关系。
https://stackoverflow.com/questions/7169639
复制相似问题