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