【问题标题】:Expose an enumeration from a wrapped COM component从包装的 COM 组件中公开枚举
【发布时间】:2011-04-08 00:25:13
【问题描述】:

我正在用 .NET 编写一个类库,它封装了一个 COM dll 并公开了其他 .NET 代码可以使用的特定功能。 COM 库定义了几个枚举,我使用了一些枚举类型作为参数,如下所示:

//C#
public void TransactionTypeSetByEnum(COMComponent.TransactionType transType)
{
    this.TransactionType = transType
}

'VB.NET'
Public Sub TransactionTypeSetByEnum( _
  ByVal transType As COMComponent.TransactionType)
    Me.TransactionType = transactionType
End Sub

但是,当我从另一个项目使用这个 .NET 包装器时,编译器看不到 COM 类型(我不想将它们暴露给使用类)。比如……

 netWrappedObject.TransactionTypeSetByEnum( //...No intellisense for the enum

有没有办法在我的 .NET 包装库中公开底层非托管枚举,而无需添加非托管 DLL 引用负责使用该库的项目?


其他背景信息:

该企业已经拥有已编译成 COM 组件的有效 VB6 代码。企业不想在 .NET 托管代码中重写这些组件,但希望能够在 .NET 应用程序中使用现有代码。我的目标不是让每个 .NET 应用程序都直接拉入 COM 组件,而是围绕现有 COM 组件编写一个 .NET“包装器”,并通过类和接口向其他 .NET 应用程序公开所需的功能。

我在使用接口设计来包装 COM dll 背后的部分想法是:如果企业稍后决定将现有的 COM dll 重写为 100% 托管的 .NET 代码会更好,我只需要要做的是用新代码实现接口并更改现有应用程序以引用新程序集并可能更改一行代码。这样就无需为每个 .NET 应用程序重写 COM dll 的实现。

在我上面的问题中,我的问题是 COM dll 有几个 enums,我想通过“包装”该 DLL 的 .NET 组件公开它们。假设 COM dll 有一个名为 ComFoo 的类,它有一个枚举调用 ComFooEnum。我希望NetFoo 类在其他项目使用NetFoo 时以某种方式公开ComFooEnum。我不希望其他项目被要求引用ComFoo 只是为了能够看到NetFoo 暴露的enum。如果我必须模仿ComFooEnum 并制作一个新的NetFooEnum,我想这就是我要做的,但我想知道是否有更好的方法。

这是一个试图解释我试图实现的封装的图表:

______________________________  
|                            |  
| Compiled VB6 COM Assembly  |  
|  Exposes class called      |  
|     ComFoo                 |  
|____________________________|   
                        ||
_____________________   ||
|                   |   ||
| Existing VB6      |   ||
| Business          |  < |
| Application       |   ||
| references ComFoo |
|___________________|

//The business is building new applications in .NET
//that need to consume ComFoo, which cannot be rewritten.
//NetFoo exposes the functionality of ComFoo.

____________________________________
|                                  |
|        .NET Wrapper Assembly     |
|    Exposes class called NetFoo   |
|  ______________________________  |
|  |                            |  |
|  | Compiled VB6 COM Assembly  |  |
|  |  Exposes class called      |  |
|  |     ComFoo                 |  |
|  |____________________________|  |
|__________________________________|
                        ||
_____________________   ||
|                   |   ||
| New .NET Business |  < |
|  Order Entry App  |   ||
| references NetFoo |   ||
|___________________|   ||
                        ||
_____________________   ||
|                   |   ||
| New .NET Business |   ||
|  Internet App     |  < |
| references NetFoo |   ||
|___________________|   

【问题讨论】:

  • 你做了什么&lt;ComVisible&gt;?这是 IDE 问题,而不是编译器问题。什么 IDE?
  • @Hans 我正在使用 VS2010。我不确定是否需要使用 。我试图让包装的 COM 组件类型对其他 .NET 项目可见,而不是对 COM 可见。 会给我带来什么?
  • 我不知道您为什么要让 ComVisible 组件对 .NET 程序可见。我怀疑您从事 COM 的时间可能太久了,我已经发布了对您的许多 COM 问题的答案。创建 ComVisible .NET 组件并在 .NET 程序中将其用作 COM 组件完全没有意义。只需直接使用程序集,无需跳过 COM 箍。完全不确定我是否在正确的轨道上,离开你的问题标题。
  • @Hans 我不确定我们是否以同样的方式理解问题。我已经更新了我的问题以尝试提供更多背景信息。回答您的其他观点:并不是从事 COM 的时间太长(实际上我只是在 6 个月前才开始专业从事软件工作),而是我工作的业务非常适应COM的世界。我正试图让企业更频繁地考虑使用 .NET,而这正是所有 COM 互操作问题出现的地方。非常感谢您的反馈并花时间查看我的问题。

标签: c# .net vb.net com interop


【解决方案1】:

这里没有魔法可用。正如您使用等效的 .NET 类型包装 COM 组件中的接口类型一样,您必须包装类型库中的其他声明。如果您不想公开 COM 枚举类型,则必须包装它们。使用 .NET 枚举类型声明。代码通过int转换很简单,但它是一个维护项目。就像 .NET 类包装器一样。确保包装 COM 类型有实际的增值作用,一对一的映射很少有用。

除非这是最终替换 COM 服务器的训练轮。没关系,它让您对需要的东西有很好的感觉。在这种情况下,您真的确实想要声明枚举。

【讨论】:

  • +1 我不明白 .Net 包装器的好处。对我来说,明显的升级路径是用具有等效签名的.Net 替换 COM 组件。该组件可用于所有 .Net 客户端。听起来这是为了使未来可能的更改更容易而进行的重构。但是现在做而不是在未来的变化中得到什么?我不明白这种情况的好处。
猜你喜欢
  • 1970-01-01
  • 2018-10-25
  • 1970-01-01
  • 1970-01-01
  • 2021-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多