我有一些希望与 Visual Studio IDE 交互的 Workflow Foundation 4 ActivityDesigners(它们是 WF4 的事实与问题无关)。
这些设计器是在一个程序集中定义的,我们称之为herpaderp.dll。最终,这个 dll 将被传送到服务器,在那里它的活动和其他代码将永远快乐地生活。
但是,在此之前,我希望我的设计人员能够检查当前的解决方案,以便为使用 herpaderp.dll 中定义的活动的人们提供更好的设计时体验。类似于“让我们使用存储在解决方案中的示例数据来测试此 Activity 配置;这是我在一个方便的组合框中找到的示例数据——请选择一个”。
现在,这很简单。这是天真的实现:
var dteo = Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(DTE));
var dte = dteo as DTE;
if(dte == null) return; // not in Visual Studio or other wierdness, bail
var samples = dte.GetSampleDatum(); // super awesome extension method
嘿,效果很好!但是有一个小问题...... herpaderp.dll现在必须引用以下程序集:
- Microsoft.VisualStudio.Shell.10.0.dll
- envdte.dll
这些程序集是 SDK 的一部分。必须将它们打包并将它们交付到服务器对我来说绝对没有意义。这就像在我的大肠中添加了另一个阑尾。
我怎样才能打破这些依赖关系,同时保留在我的设计师内部与 Visual Studio 交互的能力?
在我看来,我有三个可能的答案,没有一个是我特别满意的。
- 使用 IoC 在运行时绑定到将为我执行交互的程序集。该程序集可以引用 SDK 程序集,同时隐藏在 herpaderp 中定义的简单接口后面。不幸的是,这增加了一个不同的依赖关系,它只在设计时很重要,在服务器上是无用的。
- 在运行时使用它们的程序集限定名称加载依赖项并隐藏在
dynamic
. 这冒犯了我的类型安全育种。另外,我不确定我是否能 100% 摆脱它。 - 在运行时通过某种服务位置与 Visual Studio 包交互。我的解决方案提供了一个 Visual Studio 扩展,因此我不必担心编写它或强迫人们使用它。但为了与之互动,我不得不使用某种蹩脚的 Service Locator BS 模式废话,我满怀激情地鄙视它。服务定位器。费。此外,它还需要某种跨进程(或至少在同一进程中跨 AppDomain)通信。
选项 3 是我最好的选择,我相信。我还缺少另一个解决方案吗?我讨厌我的三个答案之一是错的吗?