How to use DuckTyping when implementations change a little?

I make a portable class library (PCL) in .NET, and it happens that when I try to abstract any behavior, I come across a very common annoyance that the .NET Framework is very possessive of its types and interfaces . It is very common to find a type that does not implement any interface, or when it does, the interface is internal.

If existing types have compatible methods (same name and signature), this is pretty simple: I used ImpromptuInterface as follows:

nakedInstanceTheDoesNotImplementAnything.ActAs<MyBeautifulInterface>();

and I get exactly what I want. Transparent and comfortable.

But what to do when some methods are slightly different?

  • Different names
  • Another call site: one is the getter property and the other is the method
  • Some methods that differ from each other, but easily adapt between them with minor changes.

It is generally recommended that you use a clean OOP approach, and we are told that we are creating and adapting. But , when you need to adapt a complex type hierarchy, it can be really tedious and complicated, and even more when you have HUGE classes, such as UIElement, Control, FrameworkElement ...

Question: Can I get ImpromptuInterface to overcome these type variations for dynamically creating adapters?

+3
source share
1 answer

, ImpromtuInterface DLR, , ActLike(), .

public class Proxy:IMyInterface {

      dynamic target;

      public int Foo(){
           return (int)target.Foo()
      } 
}

, , IDynamicMetaObjectProvider System.Dynamic.DynamicObject.

public class RoughDynamicAdapter:DynamicObject{

    public override bool TryInvokeMember(InvokeMemberBinder binder,
                                        Object[] args,
                                        out Object result){

          if(binder.Name == "Foo"){
            result = /* do your own logic */
            return true;
          }
          result = null;
          return false;
    }
}

, , .

ImpromptuInterface prefab DynamicObject, Dynamitey.

, BaseForwarder , , .

public class DynamicAdapter:Dynamitey.DynamicObjects.BaseForwarder {

     public DynamicAdapter(object target):base(target){
     }

     public override bool TryInvokeMember(InvokeMemberBinder binder,
                                         Object[] args,
                                        out Object result){
          var newName = binder.Name;
          if(newName == "Foo"){
             result = Dynamic.InvokeMember(CallTarget, "Bar", args)
             return true;
          }
          //else pass them method on as it was called
          return base.TryInvokeMember(binder, args, out result)
    }
}

new DynamicAdapter(myObject).ActLike<IMyInterface>()

+2
source

All Articles