In order to hide the concrete implementation of a class behind an interface, for example for dependency injection, I find it is useful to extract an interface with the methods and properties I am interested in. Even for generated classes I can usually make a partial class which implements the extracted interface.
But if I want to extract an interface for an external class, e.g. from a .dll, I can't find any way to do this. Is it even possible?
An interface is not extended by a class; it is implemented by a class. An interface can extend multiple interfaces.
Interfaces can inherit from one or more interfaces. The derived interface inherits the members from its base interfaces. A class that implements a derived interface must implement all members in the derived interface, including all members of the derived interface's base interfaces.
A class can implement multiple interfaces and many classes can implement the same interface.
No. An interface defines how a class should look like (as a bare minimum). Whether you implement this in a base class or in the lowest subclass doesn't matter.
The simplest approach is usually to wrap the class to implement the adapter pattern. So if we start with:
public class NastyExternalClass
{
public void Foo() { ... }
}
We add:
public interface IFooable
{
void Foo();
}
public sealed class NastyExternalClassWrapper : IFooable
{
private readonly NastyExternalClass original;
public NastyExternalClassWrapper(NastyExternalClass original)
{
this.original = original;
}
public void Foo()
{
original.Foo();
}
}
It's tedious - although it could be automated, and I wouldn't be surprised if R# or similar tools already supported this - but it generally works.
It becomes more of a problem if multiple objects need to know about each other, and use the original API... or if the original API adds callbacks which then bypass the wrapper etc. In those cases you need to be more inventive or just live with the imperfection :(
It sounds like you want to use the adapter pattern, to allow an implementation of your interface in a type you define which delegates calls to the third party library.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With