Question

Let's say you have two DLLs which contain virtually identical code. There are only minor differences between them, but those differences are important enough that need to remain distinct libraries. Actually, in my particular case, they are third-party Java libraries which have been converted to .NET DLLs using IKVM, so we cannot collapse them into one without rewriting the code ourselves. These represent slightly different versions of a server API provided by an outside supplier.

When we go to use these libraries within our code, we are forced to write two classes which are exactly the same, except that the external alias we specify is different.

For example:

extern alias Lib1;

namespace MyNamespace
{
    public Class1
    {
        private Lib1::A a = new Lib1::A();

        public Class1()
        {
            this.a.DoStuff();
        }

        // Uses Lib1 extern alias throughout
    }
}

extern alias Lib2;

namespace MyNamespace
{
    public Class2
    {
        private Lib2::A a = new Lib2::A();

        public Class1()
        {
            this.a.DoStuff();
        }

        // Totally identical to Class1, except that it uses Lib2 extern alias throughout
    }
}

All the code in Class1 is exactly the same as Class2. Just the alias is different.

When we want to update the code, we are forced to duplicate the code from one class into all the others. Then we simply replace one alias with another.

Is there a way in which we could create a single class, and simply specify dynamically which extern alias to use when we instantiate the class?

Thanks for your help.

Was it helpful?

Solution

Options:

  • Build against a single DLL, and then just switch DLL contents (i.e. build both DLLs with the same name, and just change which version you use)
  • Create a single interface with two different implementations, one of which talks to each library

Personally I'd probably go with the latter. No, there's no such context as a "dynamic extern alias".

OTHER TIPS

I would suggest defining one interface for Lib1.A and Lib2.A.

Then implement Class2 as follows

    public MyClass
    {
        private readonly ILib _lib; 

        public Class2(ILib lib)
        {
          _lib = lib
        }
        public MyMethod()
        {
            _lib.DoStuff();
        }                
    }

The you can call it as follows new MyClass(new Lib1::A()).MyMethod() or new MyClass(new Lib2::A()).MyMethod()

Having the ILib dependency injected will help unit test it too.

The best way i find to do what you say, is to use a namespace at a higher level... that way you can determine which one to call, then call the right one, in a single class.

Following Jon Skeet answer, you can create an abstract class and implement all the common "repeated" code between the two classes and mark as abstract the method that needs unique code.

That way, you are not repeating code anywhere, and thanks to polymorphism, changing context is not difficult at all.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top