7

Is it possible to dynamically compose a class from the methods contained in other Classes?

For instance. Class A, B and C have public methods named such that they can be identified easily. They need to be extracted and added to Class D. Class D, which then contains all of the implementation logic can be passed further into a system which only accepts a single instance of Class D and dynamically binds these methods to other functions.

To be clear, this is not inheritance I'm looking for. I'm literally stating that methods with different names need to be stuffed into one class. The system I pass it into understands these naming conventions and dynamically binds them (it's a black box to me).

I am going down the path of extracting the methods from A, B, and C, dynamically combining them with the source of Class D in memory and compiling them into a new Class D and then creating an instance of D and passing it forward.

public class A{  public void EXPORT_A_DoSomething(){} }
public class B{  public void EXPORT_B_DoSomethingElse(){}}
public class C{  public void EXPORT_C_DoAnything(){}}
 //should become
public class D{ 
          public void EXPORT_A_DoSomething(){} 
          public void EXPORT_B_DoSomethingElse(){}
          public void EXPORT_C_DoAnything(){}
}

Is there a way to extract the MethodInfos from class A, B and C and somehow directly attach them to Class D? If so how?

7
  • 3
    You can output your class' code to a plain text file, save it and compile it at runtime. Take a look at the CSharpCodeProvider Class and related topics to learn how to do this. Commented Mar 18, 2013 at 14:56
  • 1
    As far as I know, there's no way to copy the implementation of a method. What I'd probably do is create a DynamicObject derived class that contains instances of A, B, and C and then have the DynamicObject derived class imlpement methods with these names and simply proxy them to the contained objects. That assuming I understand what you're asking. I think this would work. Commented Mar 18, 2013 at 14:56
  • 1
    @JohnWillemse: Multicast delegates if your methods share same signature , may helpful to you Commented Mar 18, 2013 at 15:01
  • 1
    How about using reflection Will this do? msdn.microsoft.com/en-us/library/ms173183%28v=vs.80%29.aspx Commented Mar 18, 2013 at 15:01
  • @JohnWillemse, thanks for the sanity check - this is direction I'm currently headed in ;) Commented Mar 18, 2013 at 15:02

5 Answers 5

2

I would consider using the C# Class compiler. From what I can remember you can build code that is in a string and you can get an assembly as output. This then enables you to invoke methods through reflection.

There is an example on the MSDN link I have specified but I will mock one up for here once I find my project.

Sign up to request clarification or add additional context in comments.

1 Comment

I have access to the source of classes A/B/C so dynamic compilation does seem to be the most direct, 'brute force' approach. Another commenter below did bring up the complexity of merging private data within these classes though, another hurdle.
1

You won't be able to export just the methods. The methods can't really be separated from the class that they are in. (they need access to all of the member fields/properites including inherited).

I think the only thing you can do is emit a interface implementation. (even though you say it's not what you need, I don't see a way around needing the private state for those objects)

You can make a single interface which contains only the methods you need, and provide a class that supports it which contains an instance of each type of object.

public class A{  public void DoSomething(){} }
public class B{  public void DoSomethingElse(){}}
public class C{  public void DoAnything(){}}

public interface ID 
{ 
    void A_DoSomething(); 
    void B_DoSomethingElse(); 
    void C_DoAnything(); 
}

public class D : ID 
{ 
    private A a;
    private B b;
    private C c;

    public D(A a,B b, C c) { this.a=a;this.b=b;this.c=c; }

    public void A_DoSomething(){ a.DoSomething();} 
    public void B_DoSomethingElse(){ b.DoSomethingElse();}
    public void C_DoAnything(){ c.DoSomething();
}

If you need to generate this dynamically, look into Reflection.Emit. It'll be some business about how you've got to create a new assembly, and then load it dynamically into the AppDomain. I'd try to avoid that if you can.

2 Comments

I can see this as a solution though when we're talking about potentially hundreds of methods it would definitely have to be done dynamically. I can see a human upkept version where other developers upkeep the interface ID for each method they needed added -- but man what a mess that would be. I do like the "pass-through" nature of the code you proposed. One of the ideas I had was a hybrid. Dynamically writing stubs into class D that are calls to class A, B, C.. etc. I think using an interface allows you to directly attach method implementations via codedom.
Maybe you could use a t4 template to generate something like this. It wouldn't be dynamic as in 'loaded at runtime', but it may ease the burden of writing a lot of plumbing code.
0

It should actually be possible using something called "Mixins" and proxy generators. Take a look at Castle.DynamicProxy's tutorial: Mixins

Comments

0

Another solution is to define the class get and set accessors for the function as an interface, and declare the functions you are interested in.

interface iA
{
    public int a { get; set; }
}
interface iB
{
    public int b { get; set; }
}
interface iAB : iA, iB
{
}
class MyClass : iA, iB
{
    public int b { get; set; }
    public int a { get; set; }
}
static class MyClassExtender
{
    static public int Foo(this iAB ab)
    {
        int c = ab.a + ab.b;
        ab.a = c;
        return c;
    }
    static public int FooA(this iA a)
    {
        int c = ab.a + 1;
        ab.a = c;
        return c;
    }
    static public int FooB(this iB b)
    {
        int c = ab.b + 1;
        ab.a = c;
        return c;
    }

}

So now "MyClass" can use Foo, FooA, and FooB as public methods.

2 Comments

Unfortunately, the methods cannot be static. I do love extension methods, but in this particular case they wouldn't work. The methods need to be public instance members.
Just out of curiosity, what is the feature that prevents these from working? You can cause side effects using the methods above, and can use internal interfaces to hide stuff out of module. It does create a huge spread of interfaces, so I'm not sure how maintainable the design pattern is.
-1

Have you considered simply using a hash or list of delegates in you D class that point to the methods on the other classes? Alternatively, use a dynamic object (google ExpandoObject).

2 Comments

unfortunately, the methods have to be accessible via reflection by the system that will use them so this won't work.
You can still reflect over dynamic objects with a little extra work. I wouldn't write off using delegates.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.