gpt4 book ai didi

c# - Visual Studio 插件的依赖注入(inject)

转载 作者:太空狗 更新时间:2023-10-29 23:50:07 24 4
gpt4 key购买 nike

我正在开发一个 visual studio 插件,它在您的项目中接受 SQL 查询、播放请求并为结果生成一个 C# 包装器类。我想做一个尽可能简单的依赖注入(inject),其中使用我的加载项的项目提供一个类,该类可以提供项目的数据库连接字符串等。

这个接口(interface)在我的加载项中定义...

[Serializable]
public interface IDesignTimeQueryProcessing
{
public string ConnectionString { get; }
...
}

问题是:如何定义和实例化具体实现,然后从加载项中使用它?

有进展吗?

上面的接口(interface)是在加载项中定义的。我已经在目标项目中创建了对加载项的引用,编写了具体实现,并将该类的名称放在了目标项目的web.config中。现在我需要从加载项加载目标项目以使用我的具体类。

如果我使用 Assembly.Load()...

var userAssembly = Assembly.LoadFrom(GetAssemblyPath(userProject));
IQueryFirst_TargetProject iqftp = (IQueryFirst_TargetProject)Activator.CreateInstance(userAssembly.GetType(typeName.Value));

我可以成功加载我的类,但是我锁定了目标程序集,无法再编译目标项目。

If I create a temporary app domain ...

AppDomain ad = AppDomain.CreateDomain("tmpDomain", null, new AppDomainSetup { ApplicationBase = Path.GetDirectoryName(targetAssembly) });
byte[] assemblyBytes = File.ReadAllBytes(targetAssembly);
var userAssembly = ad.Load(assemblyBytes);

我在调用 ad.Load() 时收到一个找不到文件的异常,即使我的 dll 的字节在内存中也是如此。

如果我使用 CreateInstanceFromAndUnwrap()...

AppDomain ad = AppDomain.CreateDomain("tmpDomain", null, new AppDomainSetup { ApplicationBase = Path.GetDirectoryName(targetAssembly) });
IQueryFirst_TargetProject iqftp = (IQueryFirst_TargetProject)ad.CreateInstanceFromAndUnwrap(targetAssembly, typeName.Value);

我得到一个

InvalidCastException. "Unable to cast transparent proxy to type QueryFirst.IQueryFirst_TargetProject"

这让我觉得我很亲近?为什么显式转换在 Assembly.Load() 中可以正常工作,但在新创建的 AppDomain 中加载相同的程序集时却失败了?

最佳答案

我假设您的加载项将以某种方式被触发,以便开始使用 SQL 查询。

我建议您将一个单独的 .exe 文件与您的加载项捆绑在一起并在其中进行处理。

原因如下:

  1. 就我个人而言,我遇到过很多关于 AppDomain 的问题,这些问题类似于您遇到的文件锁定问题和临时域的头痛问题。您可能会遇到的另一个问题是,一旦将程序集加载到 AppDomain 中,就无法卸载。通过使用单独的进程(完成后即结束),您不必担心这个问题。
  2. 根据您要支持的项目类型,这些项目将具有依赖性。如果您可以将独立的 .exe 指向一个目录(即 bin 目录),那么管理对相关 dll 的引用将会容易得多。
  3. 如果您连接到 Visual Studio 的 Build Events (DTE.Events.BuildEvents.OnBuildBegin) 您可以终止您的进程并释放对 dll 文件的锁定。或者您可以让您的流程先制作副本。
  4. 使用独立文件进行测试/调试会容易得多。您无需担心通过附加到 Visual Studio ( How to debug a Vsix project ) 来尝试调试。

您可以使用以下方法启动/终止进程:

我认为您可以通过引用 Anatomy of a VSIX Package 直接从您的 VSIX 加载项项目中引用控制台项目的输出。 .否则,您可能需要执行一些自定义 MSBuild 操作才能将 .exe 包含在 VSIX 文件中。

包含后,您可以找到 .exe,因为它应该与您正在执行的 VSIX (Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) 在同一路径中,我会传递它加载项目的 bin 目录的路径。


顺便说一句,这不是 Dependency Injection .如果你想在 VS 扩展中使用 DI,你可以使用任何你喜欢的框架,但我认为 MEF native 支持。就个人而言,我更喜欢Ninject .在 Package 类中定义您的 Kernel 并使用它来加载您的顶级类。

关于c# - Visual Studio 插件的依赖注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35035893/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com