C# 如何防止抽象泄漏?

C# 如何防止抽象泄漏?,c#,dependencies,code-injection,abstraction,C#,Dependencies,Code Injection,Abstraction,我正在编写一个ActiveDirectory包装器,试图遵循SOLID和其他最佳实践。该接口当前为“IActiveDirectory” 我现在遇到的问题是,实现ActiveDirectory必须实现IDisposable,以处置在此包装器中创建和处置的一些资源,我不确定在尝试编写接口代码时如何解决此问题,等等。。。我不想创建一个泄漏的抽象(即装饰IActiveDirectory w/IDisposable)。由于底层依赖关系的性能,我无法使服务细化(即将资源的创建/处置范围限定为方法调用) 我目

我正在编写一个ActiveDirectory包装器,试图遵循SOLID和其他最佳实践。该接口当前为“IActiveDirectory”

我现在遇到的问题是,实现ActiveDirectory必须实现IDisposable,以处置在此包装器中创建和处置的一些资源,我不确定在尝试编写接口代码时如何解决此问题,等等。。。我不想创建一个泄漏的抽象(即装饰IActiveDirectory w/IDisposable)。由于底层依赖关系的性能,我无法使服务细化(即将资源的创建/处置范围限定为方法调用)


我目前有一个工厂,这样IActiveDirectory的用户就可以按需创建一个工厂,但我需要一种干净、方便的方式,让用户能够发出信号,表明它已经使用了资源


如何在不泄漏资源包装器抽象的情况下为消费者提供契约(即接口)?我是否应该在接口上公开实现?我的消费者或DI容器是否有办法管理此服务的生命周期?

一方面,处置资源的责任落在获得资源的人身上。您的客户机不创建ActiveDirectory,工厂创建ActiveDirectory-因此,从概念上讲,工厂必须处理ActiveDirectory

这很难,但可以实现。一个例子是web应用程序,您可以将工厂范围限制为请求的范围,并在请求完成时使用活动目录安全地处理它。另一个例子是,当您的实例由IoC容器管理时,它知道如何处理IDisposable(NInject有一些技巧可以做到这一点)


然后,如果这不适用于您,您应该承认通用解决方案并不是最有效的(这一点也不奇怪),如果您仍然想要抽象,您可以创建额外的抽象IActiveDirectory会话,它显式表示与AD的通信会话,并且出于非常自然的原因必须实现IDisposable,至少。

“我需要一种干净、方便的方式,让消费者发出信号,表示资源已使用完毕。”——这正是
IDisposable
的含义。你不能抽象所有的东西。是的,我知道这正是IDisposable的含义,我可以把它放在一个具体的类上。然而,我确实不喜欢把它放在接口上,因为我正在创建一个泄漏的抽象,我假设所有的实现都需要一个Dispose方法调用,这违反了Liskov。您认为只公开具体的sans接口更好吗?在LSP和其他标准下,
Dispose
什么都不做是完全有效的。将其放在接口上并不意味着假设所有实现都需要处理(任何不需要的实现都可以简单地添加
void Dispose(){}
),而是意味着假设某些实现需要处理(这是真的)@delnan我仍然认为这违反了Liskov的规定,因为接口至少满足了一个具体用户的需求,而且可能至少有一个实现不“需要”接口所要求的内容。尽管如此,我承认,即使是违规,在实践中也不是什么大问题,因为该方法是无效的,按照惯例,在任何用例中都不应该抛出/导致异常或意外。@delnan IMO liskov违规通常应该被认真对待,因为它们暗示要重构更干净/更可维护的代码,但我想,在这种情况下,理论和实践无法达成一致的解决方案。我的想法正是如此。我已经使用环境上下文模式创建了一个准会话,通过该会话,在调用上下文的Dispose时,服务伞下创建的任何对象都将“注册”以进行处置。在这种情况下,使用IOC来管理生存期实际上是不可能的,因为我认为在“长时间”打开之后关闭“会话”是不可接受的。