DontVoteMeDown
DontVoteMeDown

Reputation: 21465

Create a delegate with a dynamic injected class

I'm changing a processing algorithm I've made from reflection to delegate since it handles huge data and it is having performance issues(as I have learned here). So my old code is a simple reflection as shown below:

var result = method.Invoke(service, new object[] { viewModel });

Where the method is a MethodInfo, service is a service class with a common method called Add(). All services have that method(not generic tho) and this processing algorithm can run over any service, hence, service(the instance) is dynamic. It is resolved with Unity.

Here is a working demo with a similar code that I'm trying to make happen:

using System;
using System.Reflection;

// This is the delegate declaration
public delegate string ServiceDelegate(ViewModel vm);

public class Program
{
    public static void Main()
    {
        // Here the 'Service' class is created by a IoC container
        object service = DependencyInjectionSimulator.Resolve();
        Type type = service.GetType();
        MethodInfo method = type.GetMethod("Add");

        ServiceDelegate serviceDelegate = (ServiceDelegate)Delegate.CreateDelegate(typeof(ServiceDelegate), service, method);

        var car = new CarViewModel();

        Console.WriteLine(serviceDelegate(car));
    }
}

// This is the 'Service' base class. It will be created dynamically and all services has the Add() method with a 'ViewModel' inherited class
public class Service
{
    public string Add(CarViewModel input)
    {
        return input.Name;
    }
}

// All 'Add()' method of services will work with a parameter that inherits 'ViewModel'
public class ViewModel
{
    public string Name { get; set; }
}

public class CarViewModel : ViewModel
{
}

// Let's pretend this is a Unity Resolver
public static class DependencyInjectionSimulator
{
    public static object Resolve()
    {
        return new Service();
    }
}

I hope this clarifies with I'm trying to achieve, although I'm not sure if it is possible.

Upvotes: 4

Views: 395

Answers (1)

DavidG
DavidG

Reputation: 118987

Your DI framework will only ever give you an object that represents the type you are asking for, so you shouldn't ever need to worry about delegates or reflection. For example, let's update your DI simulator to this:

public static class DependencyInjectionSimulator
{
    public static TService Resolve<TService>() 
        where TService : class
    {
        //So this only works for the one type right now, but hey, it's only a simulator!
        return new Service() as TService;
    }
}

I would also suggest you use an interface for your service, it's a good habit to get into and it will help in future with things like unit testing:

public interface IService
{
    void Add(CarViewModel input);
}

public class Service : IService
{
    public void Add(CarViewModel input)
    {

    }
}

Now your code simplifies to this:

var service = DependencyInjectionSimulator.Resolve<IService>();
var car = new CarViewModel();
service.Add(car);

Upvotes: 1

Related Questions