我有一个包含3个项目的解决方案:
1)GUI可执行文件
2)包含公共API和公共接口的类库
3)实现上述接口的类的类库
我正在尝试在API中实现资源加载器,以便当GUI调用方法
所以我做的是:
我正在尝试在API中实现资源加载器,以便当GUI调用方法
API.Foo()
时,我将遍历特定文件夹(位于:.\resources)中的每个程序集,其中包含我编译的程序集的副本(#3)。
然后,我想将资源添加到列表中,并使用此列表调用界面的一部分函数(每个资源都实现该函数)。所以我做的是:
private List<IResource> m_resources;
public void Foo()
{
string resourceDir = Directory.GetCurrentDirectory() + @"\Resources";
m_resources= new List<IResource>();
foreach (var dllFile in Directory.EnumerateFiles(resourceDir))
{
IResource dllInstance;
if (TryLoadingDLL(Path.Combine(resourceDir, dllFile), out dllInstance))
{
resources.Add(dllInstance);
}
}
}
private static bool TryLoadingDLL(string dllFullPath, out IResource instanceOfDll)
{
instanceOfDll = null;
try
{
Assembly assembly = Assembly.LoadFrom(dllFullPath);
Assembly IResourceAssambly = Assembly.LoadFrom(@"C:\MyProject\MyAPI.dll");
Type[] types = assembly.GetTypes();
foreach (Type type in types)
{
var interfaces = type.GetInterfaces();
var typeOfIResource = IResourceAssambly.GetType("MyProject.IResource");
if (interfaces.Any())
{
var interfaceType = interfaces[0]; //In debuger they have the same GUID
if (interfaceType.IsEquivalentTo(typeOfIResource)) //also tried ==
{
instanceOfDll = Activator.CreateInstance(type) as IResource;
return true;
}
}
}
}
catch (Exception e)
{
Console.Error.WriteLine("Failed to load dll {0}, exception: {1}",dllFullPath, e.Message);
return false;
}
return false;
}
实际上,我一开始就使用了这个,结果相同:
List<Type> derivedTypesList = typses.Where(type => type.GetInterfaces().Contains(IWNAssambly.GetType("MyProject.IResource"))).ToList();
if (derivedTypesList.Count > 0)
{
instanceOfDll = (IResource)Activator.CreateInstance(derivedTypesList[0]);
return true;
}
但后来我将其拆分,以便更容易调试。
当我运行这些片段中的任何一个时,我确实发现有1种类型实现了该接口,但是当我尝试使用as
运算符进行强制转换时,会得到null值,并且在使用(IResource)
进行强制转换时会出现异常。异常信息如下:
{System.InvalidCastException: Unable to cast object of type 'MyProject.MyFirstResource' to type 'MyProject.IResource'.
我是一名有用的助手,可以为您进行文本翻译。
问题似乎来自类型,因此我尝试替换
var typeOfIResource = IResourceAssambly.GetType("MyProject.IResource");
使用
var typeOfIResource = typeof(MyProject.IResource);
结果是它现在根本找不到任何内容,即interfaceType.IsEquivalentTo(typeOfIResource)
总是为false。当我用调试器查看这些类型时,它们看起来完全一样,所以我不知道问题出在哪里。
首先,这是一个好的实践吗?我希望其他开发者向我提供他们的程序集,如果他们实现了IResource接口,则使用反射创建一个实例并调用所需的方法。
其次,在此时更重要的是,问题出在哪里,我该如何解决?
谢谢!!!
MEF
呢? - BradleyDotNET