views:

157

answers:

5

Hello everyone,

I'm looking at how to solve a problem and I'm not even sure this might be possible at all in C# & .NET 3.5:

Say I have a limited number of interfaces, each describing a specific, non-related set of methods. Now I have a number real-world devices which each may implement just a subset of these interfaces.

During set-up of comms with these devices they will tell me which capabilities they have. I would now like to create an object implementing the interfaces (each resembling one capability of the device) so that higher up in my application architecture I'm able to:

  • write code against the aforementioned interfaces
  • test if that generated object implements a certain interface to see if certain actions are supported

I'm not sure at all which approach to use towards this problem. Any comments or approaches most welcome!

+4  A: 

Use a mocking framework such as Moq, RhinoMocks or TypeMock Isolator

If you're looking to do something lower level, things like Castle DynamicProxy might be a good direction for you.

Ruben Bartelink
A search for duck typing might also yield results.
leppie
@leppie: Very good point. @Timo: If you use a dynamic language such as IronPython or IronRuby (or dynamic related stuff in C# 4), you might be able to achieve something useful (though you wouldnt be using actual `interface` defintions and `is` or `as` in the implementation
Ruben Bartelink
@leppie: thanks for your suggestion. I already had a look at duck typing but I wasn't sure if it would help me with the problem. I'll take another look anyways!@Ruben: thanks for your pointers to the DynamicProxy. Most interesting! I'll also have a closer look there.
Timo Kosig
A: 

It is possible, just not easy. You need to make a string which is basically a source file and then create and use a CSharpCodeProvider, which you then order to compile your code. If it works, you can manually access your created objects through reflection.

For the interested, i did it a while back, the details are a bit foggy.

RCIX
It would probably be as easy to emit il-code into a dynamic assembly in memory. However, a mocking framework could do this easier/in less code. ;)
Simon Svensson
+2  A: 

Try something like LinFu.DynamicObject.

Martinho Fernandes
Very interesting indeed. I especially like the idea of creating a mixin. I'm just a bit hesitant to use that kind of framework for production code... I'll have to look at the license. Anyways thanks for that!
Timo Kosig
It's licensed as LGPL. And you should thank Philip, not me :)
Martinho Fernandes
+1  A: 

Maybe you don't need to make this so "dynamic".

Have you checked the Abstract Factory pattern? It seems that basically what you need is to create a concrete implementation for each of your interfaces based on a device type.

You don't need to have a single class implementing lots of interfaces, it is enough to have appropriate implementation of the specific interface when your code requests it.

Each concrete implementation of your abstract factory can generate several interface implementations based on your device type.

Example:

 public interface IDeviceFactory
 {
      ISomething GetSomeInterface();
      ISomethingElse GetSomeOtherInterface();
 }

and then you implement the specific factory for each device:

public class SimpleDeviceFactory : IDeviceFactory
{
     public virtual ISomething GetSomeInterface()
     { return Something.Empty; }

     public virtual ISomethingElse GetSomeOtherInterface()
     { return new SomeSimpleConreteImplementation(); }
}

or maybe:

public class ComplexDeviceFactory : IDeviceFactory
{
     public virtual ISomething GetSomeInterface()
     { return new ComplexStuff(); }

     public virtual ISomethingElse GetSomeOtherInterface()
     { return new EvenMoreComplexStuff(); }
}

And then, finally, you create the right factory for your device:

public class DeviceFactory
{
     public static IDeviceFactory CreateForDevice(IDevice device)
     {
          DeviceType type = device.Type; // or something like this
          switch (type)
          {
              case DeviceType.Simple: 
                 return new SimpleDeviceFactory();

              case DeviceType.Complex: 
                 return new ComplexDeviceFactory();

              default:
                 throw new NotImplementedException();
          }
     }
}

Note that I have also marked IDeviceFactory method implementations as virtual, so that you can easily reuse or override specific interfaces for a specific device.

Groo
Thanks Groo, that is really a straightforward approach to the problem! As I said in my comment on my original question I would like to avoid to make the code "device centric" (create classes for every possible device) and rather have an object created based on the feedback from the device (what it is able to do).
Timo Kosig
A: 

.NET 4 might make it easier, you could use one of the already mentioned framework or go the System.Reflection route. You'll find plenty of samples on the internet.

I've done both in the past. Rolling my own il.Emit stuff and using a framework (Spring.NET in my case). For anything but the trivial stuff, use one of the frameworks.

BennyM