Question

I have a 3rd party badly designed library that I must use.
It has all sorts of types it works with, we'll call them SomeType1, SomeType2 etc.
None of those types share a common base class but all have a property named Value with a different return type.
All I want to do is to be able to Mixin this class so I'll be able to call someType1Instance.Value and someType2Instance.Value without caring what the concreate type it is and without caring what the return type is (I can use object).
So my code is currently:

public interface ISomeType<V>
{
  V Value {get; set;}
}

public interface ISomeTypeWrapper
{
  object Value { get; set; }
}

public class SomeTypeWrapper<T> : ISomeTypeWrapper
    where T : ISomeType<???>
{
  T someType;

  public SomeTypeWrapper(T wrappedSomeType)
  {
    someType = wrappedSomeType
  }

  public object Value
  {
     get { return someType.Value; }
     set { someType.Value = value != null ? value : default(T); }
  }
}

public class SomeType1
{
  public int Value { get; set; }
}

public class SomeType2
{
  public string Value { get; set; }
}

The problem is that I don't know what T might be until runtime due to the fact that I get a dictionary of objects.

I can iterate the dictionary and use reflection to create a SomeWrapperType on runtime but I would like to avoid it.

How can I mixin the concreate type of SomeType to ISomeType?
How can I know what V type parameter is? (wish I had typedefs and decltype like in c++)

How can I, with the minimum of use of reflection possible Mixin those classes with the interface/base class?

Was it helpful?

Solution

You could try the Duck Typing Extensions for Windsor. It means you will need to register each of your types.

container
    .Register(Component.For(typeof(SomeType1)).Duck<ISomeType>())
    .Register(Component.For(typeof(SomeType2)).Duck<ISomeType>());

You could probably use linq and the register AllTypes syntax to reduce code if the names are similar.

Alternatively in the short term create a factory which can return you the objects you need, implement a concrete object for each type. No you are using the interface you can remove the factory at a later date and replace it with something else with minimal impact:

public class SomeTypeWrapperFactory
{
    public ISomeType<int> CreateWrapper(SomeType1 someType1)
    {
        return new SomeType1Wrapper(someType1);
    }

    public ISomeType<string> CreateWrapper(SomeType2 someType2)
    {
        return new SomeType2Wrapper(someType2);
    }
}

public class SomeType1Wrapper : ISomeType<int> { ... }
public class SomeType2Wrapper : ISomeType<int> { ... }

Regardless of how you implement the wrapper, be the individually or using a god like class you have the ability to change how the wrapping is done and keep the rest of your code clean.

OTHER TIPS

Why SomeTypeWrapper but not SomeObjectWrapper?

public class SomeObjectWrapper : ISomeType
{
    Object _someObject;
    PropertyInfo _valuePropertyInfo;

    public SomeObjectWrapper(Object wrappedSomeObject)
    {
        _someObject = wrappedSomeObject;
        _valuePropertyInfo = _someObject.GetType().GetProperty("Value", System.Reflection.BindingFlags.Public);
    }

    public object Value
    {
        get { return _valuePropertyInfo.GetValue(_someObject, null); }
        set { _valuePropertyInfo.SetValue(_someObject, value, null); }
    }
}

Edited With .NET 3.5 using LinFu You may use LinFu instead of Castle. However, you would be using reflection anyway, both with Castle's and with Linfu's DynamicProxy, only hidden in the guts of the libraries instead of being exposed in your code. So if your requirement to avoid the use of reflection is out of performance concerns, you wouldn't really avoid it with this solution. In that case I would personally choose Orsol's solution.

However: here's an example with LinFu's ducktyping.

public interface ISomeType {
    object Value{get; set;}
}

public class SomeType1
{
  public int Value { get; set; }
}

public class SomeType2
{
  public string Value { get; set; }
}

public class SomeTypeWrapperFactory
{

    public static ISomeType CreateSomeTypeWrapper(object aSomeType)
    {
        return aSomeType.CreateDuck<ISomeType>();
    }        
}


class Program
{
    public static void Main(string[] args)
    {
        var someTypes = new object[] {
            new SomeType1() {Value=1},
            new SomeType2() {Value="test"}
        };


        foreach(var o in someTypes)
        {
            Console.WriteLine(SomeTypeWrapperFactory.CreateSomeTypeWrapper(o).Value);
        }
        Console.ReadLine();
    }
}

Since you don't know the type of the SomeType's until runtime, I would not use mixins, but the visitor pattern (I know this doesn't answer the question on how to use mixins for this, but I just thought I'd throw in my 2 cents).

With .NET 4 using dynamic See Bradley Grainger's post here on using c#4's dynamic keyword to implement the visitor pattern. In your case, reading all the "Value" properties from your dictionary of SomeType's could work like this:

public class SomeType1
{
  public int Value { get; set; }
}

public class SomeType2
{
  public string Value { get; set; }
}

public class SomeTypeVisitor
{
    public void VisitAll(object[] someTypes)
    {
        foreach(var o in someTypes) {
            // this should be in a try-catch block
            Console.WriteLine(((dynamic) o).Value);
        }

    }
}
class Program
{
    public static void Main(string[] args)
    {
        var someTypes = new object[] {
            new SomeType1() {Value=1},
            new SomeType2() {Value="test"}
        };

        var vis = new SomeTypeVisitor();

        vis.VisitAll(someTypes);            
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top