0

This might be a little unusual but all of this is to avoid code generation.

My goal: To create a dynamic class that inherits an Interface and I also want to override all public methods.

What I've got so far:

public class Program
{
    private static void Main(string[] args)
    {
        var bmw = new BMW();
        var maker = bmw.Vehicle.Maker();
        Console.WriteLine(maker);
    }
}

public class BMW : SmartCar<ICar>
{
    public BMW() : base()
    {
    }
}

public class SmartCar<T> where T : class
{
    public T Vehicle { get; set; }

    public SmartCar()
    {
        Vehicle = Activator.CreateInstance(MyTypeBuilder.CompileResultType(typeof(T))) as T;
    }
}

public interface ICar
{
    string Maker();
}

For reference the MyTypeBuilder comes from : How to dynamically create a class in C#?

And I've made a few changes:

private static void CreateMethod(MethodInfo t, TypeBuilder tb)
    {
        // MethodBuilder
        var mbuilder = tb.DefineMethod(t.Name,
            MethodAttributes.Public, // | MethodAttributes.Static, // Only works if Static is there
            t.ReturnType,
            t.GetParameters().Select(x => x.ParameterType).ToArray());

        Expression<Func<string>> expression = () => "Hi BMW";

        expression.CompileToMethod(mbuilder);
    }

If I don't put the static I get a invalid argument value. Otherwise with the static method attribute I get want I want:

DynamicType

The problem is when I try to cast it:

Vehicle = Activator.CreateInstance(MyTypeBuilder.CompileResultType(typeof(T))) as T;

Gives me a null, so to try to fight this issue, I've added in the CompileResultType a "AddInterfaceImplementation" to my dynamic class, because I have the Maker() method implemented!

But this happens: Crash

Does anyone know a way to get around this problem?

Diogo Neves
  • 556
  • 4
  • 14
  • 2
    This _really_ seems like an XY Problem. What is the _actual_ problem you are trying to solve? Just avoiding having to generate a bunch of classes? Why do you need those classes? Your `BMW` class does not look like it actually does anything so why do you need it? – maccettura Aug 07 '18 at 21:30
  • I want to be able to have a lot of SmartCars, but not having to genarate all the code every time I change the main class: BMW. And the BMW not doing anything is exactly what I want, I want to control the class behavior in runtime – Diogo Neves Aug 07 '18 at 21:37
  • I think you need to go into more detail. Why would you have to generate code if you change the `BMW` class? Describe what you want your end result to be in a broad, non-programming sense – maccettura Aug 07 '18 at 21:38
  • I understand, but what you are doing looks _very_ wrong. I am trying to help guide you in the right direction (using reflection is usually _not_ the right direction). I just need more information from you so I can give you a proper answer. – maccettura Aug 07 '18 at 21:41
  • I made this example fairly easily but I can try to explain. I want to be able to make a call to this BMW by HTTP, so the method Maker() will have an http request, but I didn't want to create Get / Post Request everytime I need to call the Maker, I wanted to figure it out, and later just pass it the url and it will give me intellisense for making this call. And basically hardcode the less possible. – Diogo Neves Aug 07 '18 at 21:44
  • I am still struggling to understand. How would having a Url give you intellisense in Visual Studio? Also, isn't BMW a car maker? Why would a BMW class have a Maker property/method? – maccettura Aug 07 '18 at 21:46
  • BMW was an example, the thing Is I have an explosed API e.g. api/BMW/maker But I don't want to hardcode theses strings nor generate the code for it, instead, I want to be able that everytime that I call bmw.Vehicle.Maker() It makes me a GET request to that URL, and I got that information in the Interface that is shared – Diogo Neves Aug 07 '18 at 21:51
  • So there is an API that exists that has an endpoint: `api/BMW/maker` and you want your class to call that endpoint inside the `Maker()` method? – maccettura Aug 07 '18 at 21:52
  • Yes, because I'll make a Nuget Package out of that call to have intellisense in all my other projects, but I'll have a lot of endpoints like Mercedes, VW and so on.. And all the end points respect the same REST criteria, but instead of generating this code, I wanted to make this SmartCar class once, and not having to worry about with more implementations in the future – Diogo Neves Aug 07 '18 at 21:56

0 Answers0