views:

112

answers:

3

I want to simulate derivation from a base class (which is unaccessible) using just an interface and an instance of the base class (as opposed to just deriving directly from the base class).

Let me try to explain better: I have an exposed interface and a (hidden) class implementation for it.

In another module, I create a 2nd implementation of the interface and pass it an instance of the hidden class from the first module.

What I want the 2nd implementation to do:

  • it delegates the interface methods to the default implementation
  • it can override any interface method
  • it can be derived from
  • [the tricky part] code from the default implementation that calls virtual methods will call the overridden methods of this class or classes derived from it.

Remember, I can't derive from the default implementation directly!

The best way to describe it is an example.

Assembly A:

internal class DefaultImpl: IMyInterface {
    public virtual void MyMethod(){

        //call a virtual method  vvvv
        Console.WriteLine(this.GetString());
    }
    public virtual string GetString(){
        return "default implementation";
    }
}

public Interface IMyInterface {
    void MyMethod();
    string GetString();
}

------

Assembly B:

class BaseExtraImpl: IMyInterface {
   public BaseExtraImpl(IMyInterface i_implementation){
       /* magic happens here */
   }
    public virtual void MyMethod(){ /*delegate to implementation*/ }
    public virtual string GetString(){ /*delegate to implementation*/ }
} 
class ExtraImpl: BaseExtraImpl{
   public ExtraImpl(IMyInterface i_implementation): base(implementation) {}

   public override string GetString(){
       return "extra implementation";
   }
}

Usage:

DefaultImpl def; 
        //  ^^^ this is initialized to an instance of DefaultImpl;
        //      it doesn't matter how.

ExtraImpl extra = new ExtraImpl(def);
extra.MyMethod(); //should print "extra implementation"
A: 

Humm, this will always output "default implementation". The only option I see is to implement your own version of IMyInterface maybe copying the code from DefaultImpl (if you are allowed) but this was really what you where avoiding to do, I think.

bruno conde
Yep, that's exactly what I'm trying to avoid :)
Cristi Diaconescu
A: 

You could see this previous post How To Access Internal Class from External Assembly.

However, the gist of it is that you can either apply the "InternalsVisibleTo" assembly attribute to Assembly A so that Assembly B can view and access the Default implementation but this only works if you have control of both assembly's source code. Otherwise you need to use reflection to create an instance of the Default in Assembly B and then in your methods call the methods on the reflected object.

Adam Gritt
I have the constraint of not being able to reference A from B (and I have to live with it). However, I CAN readily get an *instance* of the implementation in assembly B - no need for reflection.
Cristi Diaconescu
+1  A: 

What you need is mixin possibilities in c#. Unfortunately c# doesn't have those. May be you can find an answer here: http://stackoverflow.com/questions/255553/is-it-possible-to-implement-mixins-in-c

Hans van Dodewaard
Thanks for the link. It was an interesting read
Cristi Diaconescu