Ja, es gibt ähnliche Fragen, aber keine von ihnen hat mein Problem gelöst. Ich habe eine neue Lösung mit drei Projekten:C# - Fehler beim Umwandeln des Objekts in die Schnittstelle
- FirstPlugin: Bibliotheksprojekt, um DLL kompiliert.
- MainApp: Konsolenanwendung, importiert FirstPlugin.
- Gemeinsam genutzt: Gemeinsames Projekt, in dem die Schnittstelle deklariert ist. Beide FirstPlugin und MainApp Projekte haben dieses Projekt auf ihre Referenzen.
Geteilt Projekt
Der ICrawler.cs Code:
namespace Shared.Data.Structures
{
public interface ICrawler
{
void SayHello();
}
}
FirstPlugin Projekt
Der FP.cs Code:
using System;
using Shared.Data.Structures;
namespace FirstPlugin
{
public class FP : ICrawler
{
public void SayHello() {
Console.WriteLine("Hello From FirstPlugin.dll");
}
}
}
MainApp Projekt
Die Program.cs Code:
using System;
using System.Collections.Generic;
using System.Reflection;
using System.IO;
using Shared.Data.Structures;
namespace MainApp
{
class Program
{
static void Main(string[] args) {
ICollection<ICrawler> plugins = GenericPluginLoader<ICrawler>.LoadPlugins(Directory.GetCurrentDirectory() + "\\modules");
Console.ReadKey();
}
}
public static class GenericPluginLoader<T>
{
public static ICollection<T> LoadPlugins(string path) {
string[] dllFileNames = null;
if (Directory.Exists(path)) {
dllFileNames = Directory.GetFiles(path, "*.dll");
ICollection<Assembly> assemblies = new List<Assembly>(dllFileNames.Length);
foreach (string dllFile in dllFileNames) {
AssemblyName an = AssemblyName.GetAssemblyName(dllFile);
Assembly assembly = Assembly.Load(an);
assemblies.Add(assembly);
}
Type pluginType = typeof(T);
ICollection<Type> pluginTypes = new List<Type>();
foreach (Assembly assembly in assemblies) {
if (assembly != null) {
Type[] types = assembly.GetTypes();
foreach (Type type in types) {
if (type.IsInterface || type.IsAbstract) {
continue;
}
else {
if (type.GetInterface(pluginType.FullName) != null) {
Console.WriteLine("ICrawler name: {0}", typeof(ICrawler).AssemblyQualifiedName);
Console.WriteLine("Type name: {0}", type.GetInterface(pluginType.FullName).AssemblyQualifiedName);
/*
Output:
ICrawler name: Shared.Data.Structures.ICrawler, MainApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Type name: Shared.Data.Structures.ICrawler, FirstPlugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
*/
pluginTypes.Add(type);
}
}
}
}
}
ICollection<T> plugins = new List<T>(pluginTypes.Count);
foreach (Type type in pluginTypes) {
T plugin = (T)Activator.CreateInstance(type);
plugins.Add(plugin);
}
return plugins;
}
return null;
}
}
}
Der Fehler
ich diesen netten und schönen Fehler bekommen:
Additional information: Unable to cast object of type 'FirstPlugin.FP' to type 'Shared.Data.Structures.ICrawler'
Auf dieser Linie (Program.cs):
T plugin = (T)Activator.CreateInstance(type);
Ich entschied mich, diese Lösung zu erstellen und kopieren Sie die genaue GenericPluginLoader
Quelle (von MSDN).
Das Projekt, an dem ich gerade arbeite, hat einen anderen Code, aber derselbe Fehler tritt auf.
Was ist falsch an diesem Code?
Mein Build-Ausgabe:
- D: \ PluginTest \ Module \ FirstPlugin.dll
- D: \ PluginTest \ MainApp.exe
PS: Englisch ist nicht meine Muttersprache, so ... Sie kennen (╭☞ ͠ ° ͟ʖ °) ╭☞.
Überprüfen Sie, wie viele Kopien der Assembly in 'Debug, Windows, Modules' geladen sind. – SLaks