我可以在运行时动态实例化一个接口吗?好吧我可以,但有更好的方法吗?

时间:2014-11-07 20:51:27

标签: c# interface

假设我有一堆实现接口的类:

    public interface IBuilding
    {
        string WhatAmI();
    }

    Class house:IBuilding
    {
        string Ibuilding.WhatAmI(){return "A House";}
    }

    Class Skyscraper:IBuilding
    {
        string Ibuilding.WhatAmI(){return "A Skyscraper";}
    }

    Class Mall:IBuilding
    {
        string Ibuilding.WhatAmI(){return "A Mall";}
    }

然后我想动态选择实例化类的内容:

    enum buildingType { house, Skyscraper, Mall };
    string someMethodOrAnother()
    {
          string building= textboxBuildingType.Text;
          Ibuilding MyBuildingClass;
          buildingType UserSelectedClass = (buildingType) Enum.Parse(typeof(buildingType), building);        
          if (Enum.IsDefined(typeof(buildingType), UserSelectedClass) )
          {
               MyBuildingClass = (some code that dynamically creates a class instance);
          }
          else
          {
               MyBuildingClass = new house();
          }

          return MyBuildingClass.WhatAmI;
    }

现在我可以在switch语句中执行此操作,但我认为我找到了更优雅的技巧。或者是使用界面错误的整个想法?也许我需要代表呢?

2 个答案:

答案 0 :(得分:1)

如果我理解你正在尝试做什么,有几种方法可以解决这个问题,但最终你必须有一些逻辑从可用类型列表中选择一种特定类型。

一些选项(不是详尽的清单):

  • 使用反射检查程序集并确定实现所需接口的类型。

  • 使用依赖注入(如LightInject)为您进行装配检查,并为您提供可以实例化的类型列表。 DI库具有各种功能来控制如何发现类型。这是一个非常灵活的解决方案,工作已经完成。

  • 使用XML文件(或其他文件格式)来描述可以使用的类型。这不是很灵活,但它允许您列出您希望可用的类型,而不管程序集中的内容。 (显然,您不能使不存在的类型可用,但您可以隐藏现有类型而无需重新编译代码。)

最后,您将得到一个实现所需接口的类型列表。使用列表,您必须实现某种逻辑来实际选择一个您将实例化的特定类型 - 此逻辑特定于您的应用程序(可能根据列表框中的列表选择类型等):没有人可以告诉你如何做到这一点。

选择类型后,您只需使用Activator.CreateInstance()创建所选类型的实例即可。或者,如果您使用LightInject,则可以要求库为您返回特定类型的实例。

答案 1 :(得分:1)

一般情况下,我会使用DictionaryActivator.CreateInstance

Dictionary<buildingType, Type> typeMap = new Dictionary<buildingType, Type>()
{
   { buildingType.House, typeof(House) }
}

IBuilding building = (IBuilding)Activator.CreateInstance(typeMap[userSelection]);

如果这是WPF,您可以使用转换器直接从视图到视图模型执行此操作。