如何解决通过使用依赖项注入的构造函数进行反射来调用c#类方法
var fileName = string.Format(@"{0}\{1}\{2}.dll",Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)),"ProviderDLLS",$"UtilityPayments.Providers.TestProvider");
if (!File.Exists(fileName)) return null;
AssemblyName an = AssemblyName.GetAssemblyName(fileName);
Assembly assembly = Assembly.LoadFile(fileName);
Type objectType = assembly.GetType("UtilityPayments.Providers.TestProvider.Class1");
IProviderProcessor remoteAssembly = (IProviderProcessor)Activator.CreateInstance(objectType);
return await remoteAssembly.GetProviderData();
我调用类方法,该方法使用反射实现IProviderProcessor
接口。
如果我在Class1
类中声明构造函数,并使用DI添加接口,则会收到此错误:
System.MissingMethodException:未定义无参数构造函数 对于类型'UtilityPayments.Providers.TestProvider.Class1'。在 System.RuntimeType.CreateInstanceDefaultCtorSlow(布尔publicOnly, 布尔wrapExceptions,布尔fillCache) System.RuntimeType.CreateInstanceDefaultCtor(布尔publicOnly, 布尔skipCheckThis,布尔fillCache,布尔wrapExceptions)
在System.Activator.CreateInstance(Type type,Boolean nonPublic, 布尔wrapExceptions)
Class1
构造函数:
public class Class1: IProviderProcessor
{
private readonly IProviderService _providerService;
public Class1(IProviderService providerService)
{
_providerService = providerService;
}
}
如果要在构造函数中注入接口,如何使用反射调用Class1
方法?
如果删除构造函数,代码可以正常工作,但是我需要在应用程序中使用Class1
中的其他功能,这些功能是通过依赖项注入实现的。
解决方法
Activator.CreateInstance
有一个原型,允许您传递构造函数参数。它们必须按顺序包含在对象数组中,如下所示。
当然,您需要能够以某种方式获得对提供者服务的引用。
var providerService = GetProviderServiceFromSomewhere();
var arguments = new object[] { providerService };
IProviderProcessor remoteAssembly = (IProviderProcessor)Activator.CreateInstance(objectType,arguments);
,
我不得不解决这个几乎确切的问题。 我发现最简单(也许不是最好)的是使用ServiceProvider。
在要运行代码的任何类中添加ServiceProvider:
private protected IServiceProvider _serviceProvider;
您可以正常注入它:
public YourClass(IServiceProvider services){_serviceProvider = services;}
然后替换:
IProviderProcessor remoteAssembly = (IProviderProcessor)Activator.CreateInstance(objectType);
具有:
IProviderProcessor remoteAssembly = (IProviderProcessor)_serviceProvider.GetRequiredService(objectType);
谢谢您的帮助。我使用serviceprovider解决了它,并获得了注入到Class1类的构造函数中的接口的实例。
var fileName = string.Format(@"{0}\{1}\{2}.dll",Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)),"ProviderDLLS",$"UtilityPayments.Providers.TestProvider");
if (!File.Exists(fileName)) return null;
AssemblyName an = AssemblyName.GetAssemblyName(fileName);
Assembly assembly = Assembly.LoadFile(fileName);
Type objectType = assembly.GetType("UtilityPayments.Providers.TestProvider.Class1");
var constructors = objectType.GetConstructors();
var firstConstrutor = constructors.FirstOrDefault(); //assume we will have only one constructor
var parameters = new List<object>();
foreach (var param in firstConstrutor.GetParameters())
{
var service = _serviceProvider.GetService(param.ParameterType);//get instance of the class
parameters.Add(service);
}
IProviderProcessor remoteAssembly = (IProviderProcessor)Activator.CreateInstance(objectType,parameters.ToArray());
return await remoteAssembly.GetProviderData();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。