如何使用Ninject约定绑定带I前缀COM接口与同名无I前缀接口
问题原因
之前的约定绑定失败有两个核心原因:
BindDefaultInterfaces默认规则是将实现类绑定到其继承的接口,你的场景是两个接口之间的自定义映射,不属于默认规则覆盖范围- 仅扫描
AcoSDK.dll无法命中嵌入到当前程序集的COM互操作类型
解决方案
使用Ninject约定扩展的自定义绑定规则,从接口的CoClassAttribute中提取实际COM类类型完成绑定,完整配置如下:
using Ninject; using Ninject.Extensions.Conventions; using System.Runtime.InteropServices; IKernel kernel = new StandardKernel(); kernel.Bind(services => services // 同时扫描当前程序集和依赖程序集,命中嵌入的COM类型 .FromAssembliesMatching("*.dll", "*.exe") // 筛选AcoSDK命名空间下带I前缀的接口 .SelectAllInterfaces() .Where(t => t.Namespace == "AcoSDK" && t.Name.StartsWith("I")) // 自定义绑定逻辑 .BindWith((serviceType, _) => { // 生成无I前缀的目标COM接口名 string comInterfaceName = serviceType.Name.Substring(1); Type comInterface = serviceType.Assembly.GetType($"{serviceType.Namespace}.{comInterfaceName}"); if (comInterface == null) return; // 提取COM接口标记的CoClass类型 CoClassAttribute coClassAttr = (CoClassAttribute)Attribute.GetCustomAttribute(comInterface, typeof(CoClassAttribute)); if (coClassAttr == null) return; // 完成绑定,COM对象默认设为单例可按需调整 kernel.Bind(serviceType) .ToMethod(_ => Activator.CreateInstance(coClassAttr.CoClass)) .InSingletonScope(); }));
注意事项
- 无需显式访问
AcoSDKXClass,通过Attribute读取类型的方式不会触发「Interop type cannot be embedded」的编译错误 - 若COM对象存在多线程访问限制,可根据实际需求调整生命周期(
InSingletonScope/InTransientScope等)
内容的提问来源于stack exchange,提问作者Will Marcouiller
相关产品推荐
相关产品推荐

