由于我处理反射的数据量很大并且存在性能问题(如我所了解的here),因此我正在将自己从反射到委托的处理算法进行更改。所以我的旧代码是一个简单的反映,如下所示:
var result = method.Invoke(service, new object[] { viewModel });
方法是MethodInfo
的地方,service
是具有称为Add()
的通用方法的服务类。所有服务都具有该方法(不是通用方法),并且该处理算法可以在任何服务上运行,因此,服务(实例)是动态的。通过Unity可以解决。
这是一个working demo,具有我想要实现的类似代码:
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();
}
}
尽管我不确定是否有可能,但我希望通过尝试达到的目的可以澄清这一点。
答案 0 :(得分:1)
您的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;
}
}
我还建议您为服务使用接口,这是一种良好的习惯,并且将来会在单元测试之类的方面有所帮助:
public interface IService
{
void Add(CarViewModel input);
}
public class Service : IService
{
public void Add(CarViewModel input)
{
}
}
现在您的代码简化为:
var service = DependencyInjectionSimulator.Resolve<IService>();
var car = new CarViewModel();
service.Add(car);