我可以在运行时动态实例化一个接口吗?好吧我可以,但有更好的方法吗?(Can I dynamically instantiate an interface at runtime? Well Yes I can but is there a better way?)

其他开发 IT屋
百度翻译此文   有道翻译此文
问 题

Say I have a bunch of classes that implement an 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";}
    }

And then I want to dynamically choose what to instantiate the class:

    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;
    }

Now I could do this in a switch statement, but I thought I had found a more elegant technique. Or is the whole idea of using an interface wrong? Perhaps I need a delegate instead?

解决方案

If I understand what you're trying to do correctly, there are several ways to go about this but at the end of the day you'll have to have some logic that picks one particular type from a list of available types.

Some options (not an exhaustive list):

  • Use reflection to inspect your assemblies and determine what types implement the interface you want.

  • Use dependency injection (like LightInject) to do the assembly inspection for you and give you a list of types you can instantiate. DI libraries have various features to control how to discover types. This is a very flexible solution and the work is done for you.

  • Use an XML file (or other file format) to describe types that can be used. This is not very flexible but it allows you to list the types you want to be available regardless of what's in the assemblies. (Obviously, you can't make a non-existent type available but you can hide existing types without recompiling the code.)

At the end, you'll end up with a list of types that implement the interface you need. With the list you have to implement some kind of logic to actually pick one particular type that you'll instantiate - this logic is specific to your application (maybe pick the type based on a list in a listbox, etc.): no one can tell you how to do this.

Once you pick the type, you can just use Activator.CreateInstance() to create an instance of the type you picked. Alternatively, if you use LightInject, you can ask the library to return an instance of the specific type for you.

本文地址:IT屋 » Can I dynamically instantiate an interface at runtime? Well Yes I can but is there a better way?

问 题

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



  public interface IBuilding 
{
string WhatAmI();
}

类别: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 =(一些动态创建类实例的代码);
}
其他
{
MyBuildingClass = new house();
}

返回MyBuildingClass.WhatAmI;
}


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


解决方案

如果我理解你正在尝试做什么,有几种方法可以去关于这一点,但在一天结束时,你必须有一些逻辑从可用类型列表中选择一种特定类型。



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




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


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


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




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



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


本文地址:IT屋 » 我可以在运行时动态实例化一个接口吗?好吧我可以,但有更好的方法吗?

官方微信
扫一扫关注IT屋
微信公众号搜索 “ IT屋 ” ,选择关注
与百万开发者在一起
}