bbs*_*nbb 5 c# visual-studio-addins visual-studio
我正在开发一个visual studio插件,它在你的项目中接受SQL查询,播放请求并为结果生成一个C#包装器类.我想做一个最简单的依赖注入,其中使用我的加载项的项目提供了一个类,可以提供项目的数据库连接字符串等.
此接口在我的加载项中定义...
[Serializable]
public interface IDesignTimeQueryProcessing
{
public string ConnectionString { get; }
...
}
Run Code Online (Sandbox Code Playgroud)
问题是:如何定义和实例化具体实现,然后从加载项中使用它?
上面的接口在加载项中定义.我在目标项目中创建了一个对加载项的引用,编写了具体的实现,并将此类的名称放在目标项目web.config中.现在我需要从加载项加载目标项目以使用我的具体类.
如果我使用Assembly.Load()...
var userAssembly = Assembly.LoadFrom(GetAssemblyPath(userProject));
IQueryFirst_TargetProject iqftp = (IQueryFirst_TargetProject)Activator.CreateInstance(userAssembly.GetType(typeName.Value));
Run Code Online (Sandbox Code Playgroud)
我可以成功加载我的类,但我锁定目标程序集,不能再编译目标项目.
如果我创建一个临时的应用程序域 ...
AppDomain ad = AppDomain.CreateDomain("tmpDomain", null, new AppDomainSetup { ApplicationBase = Path.GetDirectoryName(targetAssembly) });
byte[] assemblyBytes = File.ReadAllBytes(targetAssembly);
var userAssembly = ad.Load(assemblyBytes);
Run Code Online (Sandbox Code Playgroud)
我在调用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);
Run Code Online (Sandbox Code Playgroud)
我得到了
InvalidCastException的."无法转换透明代理以键入QueryFirst.IQueryFirst_TargetProject"
这让我觉得我非常接近?为什么使用Assembly.Load()进行显式转换可以正常工作,但是在新创建的AppDomain中加载相同的程序集时会失败?
我假设您的加载项将以某种方式被触发,以便开始使用 SQL 查询。
我建议您将一个单独的 .exe 文件与您的加载项捆绑在一起,并在其中进行处理。
原因如下:
DTE.Events.BuildEvents.OnBuildBegin),您可以终止进程并释放 dll 文件上的锁。或者您可以先让您的流程进行复制。您可以使用以下方法来启动/终止进程:
我认为您可以通过 VSIX 包的引用剖析 直接从VSIX添加项目中引用控制台项目的输出。否则,您可能需要执行一些自定义 MSBuild 才能将 .exe 包含在 VSIX 文件中。
一旦包含它,您就可以找到 .exe,因为它应该与执行 VSIX ( Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) 位于同一路径中,并且我会将其传递给已加载项目的 bin 目录的路径。
顺便说一句,这不是依赖注入。如果你想在 VS 扩展中使用 DI,你可以使用任何你想要的框架,但我认为MEF是原生支持的。就我个人而言,我更喜欢Ninject。定义您的Kernel内部类Package并使用它来加载您的顶级类。
| 归档时间: |
|
| 查看次数: |
881 次 |
| 最近记录: |