[英]How to dynamically load a DLL and use a class in it (that implements a known interface) [C#]
假設我有3個DLL(BlueCar,RedCar,YellowCar),每個DLL都有一個命名類(BlueCarClass等),它們也都實現了相同的接口Car,並且都是從相同的命名空間(Car_Choices)構建的。 因此,DLL在編譯之前看起來像這樣:
namespace Car_Choices
{
public interface Car
{
void What_Color();
}
public class BlueCarClass : Car
{
public void What_Color()
{
MessageBox.Show('The color is blue.');
}
}
}
DLL的名稱將為“ BlueCar.dll”。
在主程序中,用戶選擇他們想要的汽車顏色,並根據其選擇僅動態加載適當的DLL並運行What_Color()。 主程序具有Car接口的副本。 現在,我有以下內容,但是它不起作用。
static void Main()
{
string car_choice = win_form_list.ToArray()[0]; //gets choice from a drop down
Assembly car_assembly = Assembly.Load(car_choice); //car_choice is BlueCar
Type car_type = car_assembly.GetType("Car");
Car car = Activator.CreateInstance(type) as Car;
car.What_Color();
}
我也嘗試過
static void Main()
{
string car_choice = win_form_list.ToArray()[0]; //gets choice from a drop down
ObjectHandle car_handle = Activator.CreateInstance(assembly_name, "Car_Choices."+ car_choice);
Car car= (Car)handle.Unwrap();
car.What_Color();
}
有什么幫助嗎? 我是否需要進行結構上的更改(例如將每個汽車顏色DLL放入其自己的名稱空間中)? 還是我不了解如何從DLL中正確加載和使用類。
編輯:這是我必須使用的解決方案,以防有人在尋找更詳細的答案。
項目1:共享接口(作為類庫)Car_Interface.cs
namespace Car_Interface
{
public interface ICar_Interface
{
char Start_Car();
}
}
編譯為Car_Interface.dll,在接下來的2個項目中引用DLL。
項目2:汽車接口實現,作為類庫BlueCar.cs
namespace BlueCar_PlugIn
{
public class BlueCar : Car_Interface.ICar_Interface
{
public char Start_Car()
{
MessageBox.Show("Car is started");
}
}
}
編譯成BlueCar_PlugIn.dll
項目3:主程序/驅動程序Program.cs
namespace Main_Program
{
public class Program
{
static void Main()
{
Assembly assembly = Assembly.Load(DLL_name); //Where DLL_name is the DLL you want to load, such as BlueCar_PlugIn.dll
Type type = (Type)assembly.GetTypes().GetValue(0); //Class that implements the interface should be first. A resource type could also possibly be found
//OR
Type type = (Type)assembly.GetType(DLL_name + class_name); //In this case, BlueCar_PlugIn.BlueCar
Car_Interface.ICar_Interface new_car = (Car_Interface.ICar_Interface)Activator.CreateInstance(type);
new_car.Start_Car();
}
}
}
現在,如果將兩個DLL都移到bin(或將程序編譯到的任何位置)中並運行它,它將能夠動態加載BlueCar_PlugIn.dll,但不必運行它(例如,如果您有YellowCar_PlugIn.dll和也具有類似實現的RedCar_PlugIn.dll,只需加載一個程序即可運行。
您的代碼不起作用,因為例如, BlueCarClass不實現應用程序程序集中的Car ,因為基類的完全限定名稱不同。 BlueCar裝配中的Class Car可能具有完全合格的名稱
BlueCar.Car,BlueCar,版本= 1.0.0.0,文化=中性,公鑰=空
但是您的應用程序中的Car類具有不同的完全限定名稱,例如:
SomeApp.Car,SomeApp,Version = 1.0.0.0,Culture = neutral,PublicKey = null
即使將類放在相同的名稱空間中,全名仍然是不同的,因為它包含程序集名稱。
有多種方法可以實現所需的結果:可以使用MEF ,也可以自己創建更輕量的內容。
您的解決方案至少需要3個程序集:
PS實際上,您可以通過合並#1和#3並使用#2引用#3而不是#1來使用2個程序集來執行此操作。 它將起作用,但是由於在邏輯上不正確,因為您引入了交叉引用。 我認為這種方法很香。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.