【发布时间】:2013-11-02 05:22:29
【问题描述】:
我正在编写一个 Active Directory 包装器,试图遵循 SOLID 和其他最佳实践。接口当前为“IActiveDirectory”。
我现在遇到的问题是实现 ActiveDirectory 必须实现 IDisposable 以处理在此包装器中创建和处理的一些资源,我不确定在尝试对接口进行编码时如何解决这个问题,等等...我不想创建一个泄漏的抽象(即用 IDisposable 装饰 IActiveDirectory。)由于底层依赖。
我目前有一个工厂,以便 IActiveDirectory 的消费者可以按需创建一个工厂,但我需要一种干净、方便的方式让消费者发出信号,表明资源已完成。
如何在不泄露资源包装抽象的情况下为消费者提供合同(即接口)?我应该只公开没有接口的实现吗?有没有办法让我的消费者或我的 DI 容器管理此服务的生命周期?
【问题讨论】:
-
“我需要一种干净、方便的方式让消费者发出信号,表明它已使用资源。” -- 这正是
IDisposable的含义。你不能抽象出一切。 -
是的,我知道这正是 IDisposable 的含义,我将它放在一个具体的类上没有问题。但是,我确实不喜欢将它放在接口上,因为我正在创建一个泄漏的抽象,据此我假设所有实现都需要一个 Dispose 方法调用,这违反了 Liskov。您认为只公开没有接口的混凝土会更好吗?
-
在 LSP 和其他标准下,
Dispose什么都不做是完全有效的。将它放在接口上并不意味着假设所有实现都需要处理(任何不能简单地添加void Dispose() {}的实现),它意味着假设 some 实现需要处理(这是真的)。 -
@delnan 我仍然认为这违反了 Liskov 正是因为接口正在弯曲到至少一个具体的需求,并且至少有一个实现可能不需要“需要”接口要求什么。尽管如此,我承认即使是违规行为,在实践中也不是什么大问题,因为该方法是无效的,并且按照惯例,在任何用例中都不应该抛出/导致异常或意外。
-
@delnan IMO liskov 违规行为通常应该被认真对待,因为它们暗示重构为更清洁/更可维护的代码,但我认为在这种情况下理论和实践无法收敛到解决方案。
标签: c# dependencies code-injection abstraction