【问题标题】:C# - Create new objects of 'interface-represented-classes' within a static classC# - 在静态类中创建“接口表示类”的新对象
【发布时间】:2017-07-21 07:30:29
【问题描述】:

我有一个想要扩展插件功能的应用程序。我遵循这种方法:

Creating a simple plugin mechanism

我的应用程序有一个类 Table 和一个静态类 TableManager 来管理(添加、获取)表对象。 TableManager 应该是一个静态类。为了使插件编写者也可以访问所有当前表对象,我想将“TableManager”和“Table”放在自己的 dll 中。我不能简单地将 Table 的整个实现放到 dll 中,因为 Table 内部有很多依赖代码。所以我在dll中创建了一个Table的接口,我的应用程序中的Table类实现了这个接口。

MainApplication 中的“表”类:

public class Table : ITable
{
    private string _name;
    public Table (string newName)
    {
       _name = newName;
    }
    // Here is much more code
}

dll:

public static class TableManager
{  
    private static Dictionary<string, ITable> _tableDict = new Dictionary<string, ITable>();
        
    public static Dictionary<string, ITable> getDict
    {
        get { return _tableDict; }
    }
        
    public static void addTable(string name)
    {
        // This is the line where the fault occurs:
        _tableDict[name] = new ITable(name);
    }
}


public interface ITable
{
    string name { get; set; }
}

现在的问题是,我无法像之前使用 Table-objects 那样在 TableManager 中创建新的 ITable-objects,因为我无法创建接口的新实例。我该如何解决这个问题?

【问题讨论】:

  • 你不能启动一个接口的实例。您需要在一个类中实现接口并启动该类的实例。你的代码编译了吗?
  • 我发布的代码只是一个示例,在我发布的这个版本中,由于错误而无法编译。此外,由于我想创建新的 ITable 时收到错误消息,我的真实代码也无法编译。您能否根据我上面发布的代码发布您的解决方案的代码示例?
  • 1.确保 Table 实现 ITable (public class Table : ITable)。 2.将addTable改为_tableDict[name] = new Table(name);
  • 你的第一个改动也是在我的真实代码中实现的,只是这里忘记加了,不好意思! (现在更新)第二个更改是不可能的,因为在 dll 项目中,我的主应用程序中的普通“表”类是未知的。所以我不能创建一个新的 Table 实例,因为我只知道 dll 项目中的接口。
  • “某人”需要知道如何创建实现接口的具体类的有效对象。寻找“依赖注入”或“(抽象)工厂模式”。如果TableManager 的 DLL 一定不知道具体的Table 类,那么必须有第三个库“知道”(并且“被TableManager 知道”),它基本上告诉TableManager:“如果你需要一个实现 ITable 的新实例,请问我,我知道如何为你获取。” --- 或者走反思的道路......但是有龙。

标签: c# dll plugins interface


【解决方案1】:

正如Corak 在他的评论中提到的那样,如果您需要以某种方式TableManager 中创建Table 对象,您需要了解@987654325 的人 @ 并且知道如何构造它。换句话说,您需要一个可以创建通过ITable 接口表示给客户端的对象的工厂。

如何实现并不那么重要——它可以是一个单独的工厂对象,也可以是ITable 接口中的工厂方法。

这是一个带有工厂对象的示例:

添加到主应用程序:

public class TableFactory : ITableFactory
{
    public ITable NewTable(string name)
    {
        return new Table(name);
    }
}

添加到dll:

public interface ITableFactory
{
    ITable NewTable(string name);
}

public class TableManager
{  
    private ITableFactory factory;

    public TableManager(ITableFactory factory)
    {
        this.factory = factory;
    }

    public void addTable(string name)
    {
        _tableDict[name] = factory.NewTable(name);
    }

    /* the rest of your code */
}

查看实时示例at Rextester

【讨论】:

    【解决方案2】:

    正如我在评论中所说,您不能创建接口实例。您需要创建一个实现接口的类。 考虑以下代码。

    public interface ITable
    {
        string Name { get; set; }
    }
    
    public class Table : ITable
    {
        public Table(string name)
        {
            this.Name = name;
        }
        public string Name {get;set;}
    } 
    
    public static class TableManager
    {  
        private static Dictionary<string, ITable> _tableDict = new Dictionary<string, ITable>();
    
        public static Dictionary<string, ITable> getDict
        {
            get { return _tableDict; }
        }
    
        public static void addTable(string name)
        {
            _tableDict[name] = new Table(name);
        }
    }
    

    希望这能帮助您解决问题。

    【讨论】:

    • 啊现在我明白你的意思了。这是我以前的方式。但现在我想将 TableManager 和 Table 提取到自己的 dll 中,如示例中所示。这也意味着 dll 不知道类“表”。因此,我无法在我的 dll 中创建“表”对象。或者有没有办法让 'Table' 类为 dll 所知,而无需将 'Table' 的整个实现放到 dll 中?
    【解决方案3】:

    你需要在类中继承接口

      public class Table : ITable
    

    它们初始化 Table 类而不是 ITable 接口。不能启动接口。

    【讨论】:

    • 谢谢!我只是在这里的示例代码中忘记了它,在我的实际应用程序中它已经实现了。我现在编辑了这个问题。 ;)
    猜你喜欢
    • 1970-01-01
    • 2019-09-27
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    • 2011-07-12
    • 2018-03-27
    • 2018-04-20
    • 1970-01-01
    相关资源
    最近更新 更多