如何在控制台程序和DLL之间使用通用的类/接口?

时间:2016-05-28 05:52:44

标签: c# .net dll interface dynamic-linking

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

我希望DLL有一个函数,它创建并返回数据类型的对象" 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();
    }
}

基本上,我的接口有一个返回PersonData类型对象的函数。

我想将这两个文件分发给我的客户端,因此他们可以根据这些文件编写DLL代码。因此,一个客户端将创建一个返回PersonData对象的DLL,其国籍设置为" American",另一个客户端将返回一个国籍设置为日语的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,并在每个DLL中获取GetPerson()返回的对象。这意味着,我想在我的Main程序中包含相同的两个IPerson.cs和Common.cs文件,然后创建一个PersonData类型的对象,并获取GetPerson()方法的返回值,然后做一些工作用它。我的主要看起来像这样:

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()方法的返回值放入&#34; object&#34;的列表中。类型。

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

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

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

  

未处理的类型&#39; System.InvalidCastException&#39;发生了   在MainProgram.exe中

据我所知,即使我的主程序中有相同的数据类型PersonData,程序也会将其视为与我的DLL返回的PersonData对象不同的东西。

所以这是我的问题;我将如何使用像IPerson这样的接口,以及一个常见的数据类型,比如PersonData,我的DLL和主程序都可以共享?我的实际程序有更复杂的数据类型,因此我无法返回类似标准数据类型的数组。我需要能够返回用户定义的数据类型,如PersonData。

提前致谢!

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

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

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

dynamic person = item;

类似于第三方DLL的类或接口结构仍然是不同的类或接口,只要那些类/接口来自不同的程序集。

您可以尝试AutoMapper,以后可以将类型转换为您的本地类型。 here