假设我有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.');
}
}
}
Run Code Online (Sandbox Code Playgroud)
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();
}
Run Code Online (Sandbox Code Playgroud)
我也试过了
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();
}
Run Code Online (Sandbox Code Playgroud)
有帮助吗?是否需要进行结构更改(例如将每个汽车颜色DLL放入其自己的命名空间中)?或者我不理解如何适当地加载和使用DLL中的类.
编辑:这是我开始工作的解决方案,以防有人在寻找更详细的答案.
PROJECT 1:共享接口(作为类库)Car_Interface.cs
namespace Car_Interface
{
public interface ICar_Interface
{
char Start_Car();
}
}
Run Code Online (Sandbox Code Playgroud)
编译成Car_Interface.dll,在接下来的2个项目中引用DLL.
PROJECT 2:Car接口实现,作为类库BlueCar.cs
namespace BlueCar_PlugIn
{
public class BlueCar : Car_Interface.ICar_Interface
{
public char Start_Car()
{
MessageBox.Show("Car is started");
}
}
}
Run Code Online (Sandbox Code Playgroud)
编译成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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果您将两个DLL移动到bin(或编译到的程序)并运行它,它将能够动态加载BlueCar_PlugIn.dll但不一定需要它运行(例如,如果你有YellowCar_PlugIn.dll和还有类似实现的RedCar_PlugIn.dll,只需要加载一个以使程序工作).
您的代码不起作用,因为例如,BlueCarClass不实现应用程序集中的Car,因为基类的完全限定名称不同.BlueCar程序集中的Car类可能具有完全限定名称
BlueCar.Car,BlueCar,Version = 1.0.0.0,Culture = neutral,PublicKey = null
但是你的应用程序中的Car类具有不同的完全限定名称,就像这样
SomeApp.Car,SomeApp,Version = 1.0.0.0,Culture = neutral,PublicKey = null
即使您将类放在同一名称空间中,全名仍然不同,因为它包含程序集名称.
有多种方法可以实现您想要的结果:您可以使用MEF,也可以自己创建更轻量级的东西.
您的解决方案需要至少有3个程序集:
PS实际上你可以通过合并#1和#3使用2个程序集来做到这一点,并使#2引用#3而不是#1.它会起作用,但它在逻辑上是不正确的,因为你引入了交叉引用(隐式).在我看来,这种方法闻起来.
| 归档时间: |
|
| 查看次数: |
129 次 |
| 最近记录: |