C# 使用动态注入类创建委托

C# 使用动态注入类创建委托,c#,reflection,dependency-injection,delegates,ioc-container,C#,Reflection,Dependency Injection,Delegates,Ioc Container,我正在将我制作的一个处理算法从反射改为委托,因为它处理大量数据,并且存在性能问题(如我所知)。因此,我的旧代码是一个简单的反映,如下所示: var result = method.Invoke(service, new object[] { viewModel }); 如果方法是MethodInfo,service是一个服务类,它有一个名为Add()的通用方法。所有服务都有该方法(不是泛型tho),并且该处理算法可以运行在任何服务上,因此,服务(实例)是动态的。它是团结一致解决的 下面是一个示

我正在将我制作的一个处理算法从反射改为委托,因为它处理大量数据,并且存在性能问题(如我所知)。因此,我的旧代码是一个简单的反映,如下所示:

var result = method.Invoke(service, new object[] { viewModel });
如果方法是
MethodInfo
service
是一个服务类,它有一个名为
Add()
的通用方法。所有服务都有该方法(不是泛型tho),并且该处理算法可以运行在任何服务上,因此,服务(实例)是动态的。它是团结一致解决的

下面是一个示例,其中包含我正在尝试实现的类似代码:

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();
    }
}

我希望这能澄清我试图实现的目标,尽管我不确定这是否可行。

您的DI框架只会给您提供一个表示所需类型的对象,因此您不必担心委托或反射。例如,让我们将DI模拟器更新为:

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;
    }
}
现在,您的代码简化为:

var service = DependencyInjectionSimulator.Resolve<IService>();
var car = new CarViewModel();
service.Add(car);
var service=DependencyInjectionSimulator.Resolve();
var car=新的CarViewModel();
服务。添加(汽车);

我根本不明白你为什么需要反思或委托。
DependencyInjectionSimulator.Resolve方法首先应该返回正确的类型,这意味着您可以像调用任何其他对象一样调用它的方法。@DavidG它没有。本例中的解析器返回一个对象,我不能在对象中调用
.Add()
,对吗?或者我遗漏了什么?但我是说你的DI模拟器并没有模拟真正的DI服务是如何工作的。@DavidG。但这是我能得到的最接近真正的DI服务。事实上,我在真实代码中得到的错误是相同的,所以看起来非常接近。有一种更好的方法可以在小提琴中模拟真实的DI行为吗?我有这个选择,但我不能这样做。我的场景是这样的:我有数百个服务,它们有
Add()
,但是视图模型在每个
Add()
方法上都会发生变化。在这个过程中,我只有服务的名称作为字符串,这就是为什么我首先使用反射。我使用
Actvator.CreateInstance
创建该viewModel的实例,并使用该视图模型对服务的
Add()
方法调用
Invoke
。一切都是动态的,这就是为什么我不能使用通用解析器。如果有什么不清楚的地方,请告诉我。看起来你的实现出了很大的问题,但是如果你不了解你的代码库,我就没什么可说的了。我觉得这很奇怪,因为在上面的代码中,您知道模型的类型,因此将其包含在解析器中也不是一个巨大的飞跃。示例中的模型类型是固定的,但在原始代码中没有。一切都是动态的:解析服务时使用我通过反射恢复的类型;viewModel是使用
Activator.CreateInstance
创建的,并在通过
Invoke
传递到服务的
Add()
方法之前动态填充。处理是一个动态导入工具,它从另一个数据库收集数据,并通过该处理将数据包含在目标数据库中。
var service = DependencyInjectionSimulator.Resolve<IService>();
var car = new CarViewModel();
service.Add(car);