如何在控制台程序和 DLL 之间使用公共 Class/Interface?

How to use a common Class/Interface between a Console Program and a DLL?

我正在开发一个应用程序(.NET 框架 + C#),我在其中开发了一堆 DLL 并由客户发送给我,我将它们放在一个文件夹中并从我的主控制台程序中读取。为了为简单起见,我将使用一个相当抽象的例子来解释它,它恰当地代表了我原来的问题。

我希望 DLL 具有一个函数,该函数创建并 returns 一个数据类型 "PersonData" 的对象。 PersonData 具有三个变量,即 personName、personAge 和 personNationality。数据类型 PersonData 是一个结构,如下所示:

namespace CommonStuff
{
    public static class Common
    {
        public struct PersonData
        {
            string name;
            int age;
            string nationality;

            // Properties go here.

            // Constructor goes here.
        }
    }
}

以上内容保存在名为 Common.cs.

的文件中

然后我有一个界面,保存在IPerson.cs中,看起来像这样:

namespace CommonStuff
{
    public interface IPerson
    {
        Common.PersonData GetPerson();
    }
}

基本上,我的界面有一个函数,return是一个 PersonData 类型的对象。

我想将这两个文件分发给我的客户,这样他们就可以根据这些文件编写他们的 DLL。因此,一个客户端将创建一个 DLL,其中 return 是一个 PersonData 对象,国籍设置为 "American",另一个客户端将 return 一个国籍设置为日语的 PersonData 对象。例如,一个 DLL 看起来像这样:

namespace CreateAmerican
{
    public class CreateAmerican : CommonStuff.IPerson
    {
        public CommonStuff.Common.PersonData GetPerson()
        {
            CommonStuff.Common.PersonData person = new CommonStuff.Common.PersonData();
            person.Name = "Jennifer";
            person.Age = 23;
            person.Nationality = "American";
            return person;
        }
    }
}

然后,在我的主程序中,我想在 运行 时间读取那些我预先放在文件夹中的 DLL,并获取由 GetPerson returned 的对象() 在每个 DLL 中。这意味着,我想在我的主程序中包含相同的两个 IPerson.cs 和 Common.cs 文件,然后创建一个 PersonData 类型的对象,并获取 GetPerson() 方法的 return 值进入它,然后用它做一些工作。我的主图是这样的:

static void Main(string[] args)
{
    List<object> dllResultList = null;
    LoadDllClassesToList(Directory.GetCurrentDirectory(), out dllResultList);

    foreach(object item in dllResultList)
    {
        CommonStuff.Common.PersonData person = (CommonStuff.Common.PersonData)item;
        Console.WriteLine(String.Format("Name : {0}, Age : {1}, Nationality : {2}", person.Name, person.Age, person.Nationality));
    }
    Console.ReadLine();
}

LoadDllClassesToList()方法在运行时读取DLL,并将GetPerson()方法的return值放入"object"类型的列表中。

当我 运行 程序时,一切正常,直到我到达以下行:

CommonStuff.Common.PersonData person = (CommonStuff.Common.PersonData)item;

在那里,它抛出如下异常:

An unhandled exception of type 'System.InvalidCastException' occurred in MainProgram.exe

据我了解,即使我在主程序中具有相同的数据类型 PersonData,该程序仍将其视为与我的 DLL returns 中的 PersonData 对象不同的东西。

这是我的问题;我将如何使用像 IPerson 这样的接口和像 PersonData 这样的通用数据类型,我的 DLL 和主程序都可以共享它们?我的实际程序有更复杂的数据类型,所以我不能 return 标准数据类型数组之类的东西。我需要能够 return 用户定义的数据类型,例如 PersonData。

提前致谢!

为共享 类 和接口提供程序集而不是源代码。客户和您将 link 使用相同的程序集,代码将正常工作。

或者您可以放弃类型安全并使用反射或动态来使用客户端的对象。

最好的选择是将您的 interfaces 设置在单独的库中,客户可以使用它。

如果由于任何原因无法共享您的程序集,恐怕唯一的选择是使用 dynamic 类型或 reflection.

dynamic person = item;

class 的相同结构或第 3 方 DLL 中的接口仍然是不同的 class 或接口,只要那些 classes/interfaces 来自不同的程序集。

您可能想尝试一下 AutoMapper,它稍后可以将字体翻译成您当地的字体。 here