'Is it possible to superimpose an interface on an external class in C#?

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?



Solution 1:[1]

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 :(

Solution 2:[2]

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.

Solution 3:[3]

No, you can't change classes that are not under your control. Some alternatives:

Inheritance: You can create a sub-class that does implement an interface by using base class methods

Encapsulation: You can "wrap" the external class by making it a part of a larger class which implements your interface, and passing through the interface methods to the inner class.

Sometimes inheritance isn't an option (like when the base class is sealed), but encapsulation should be feasible in most cases.

Solution 4:[4]

The adapter pattern can be made easier using the ImpromptuInterface library:

using ImpromptuInterface;
using Dynamitey;

public interface IMyInterface {
  string Prop1 { get; }
  long Prop2 { get; }
  Guid Prop3 { get; }
  bool Meth1(int x);
}

//Anonymous Class
var anon = new {
  Prop1 = "Test",
  Prop2 = 42L,
  Prop3 = Guid.NewGuid(),
  Meth1 = Return<bool>.Arguments<int>(it => it > 5)
}

var myInterface = anon.ActLike<IMyInterface>();

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jon Skeet
Solution 2 devdigital
Solution 3 D Stanley
Solution 4 Geir Sagberg