csproj文件中的多个提示路径来自文本文件变量
上下文:在我们的应用程序中有两个独立的dll,它们是为不同类型的硬件配置的变量存储库。这些dll具有相同的名称并从我们的应用程序中引用,现在每次如果我们想要测试我们必须复制的不同类型的硬件相关的dll到应用程序运行的位置。 我正在寻找一种解决方法。
参考文献:我见过以下post,
1) .csproj程序集的多个提示路径
2) https://whathecode.wordpress.com/2012/10/07/conditional-project-or-library-reference-in-visual-studio/
问题:我可以在文本文件中声明一个变量,如 type1
并在我的csproj文件中导入该文本文件并为我的应用程序分配适当的引用吗?
任何帮助..
以下是复制我们项目的测试应用程序。 SignalPool1,SignalPool2具有相同的类名,并且是我们项目的两个不同位置可用的两种不同硬件配置的存储库。 如果我们想测试硬件1,我们将删除当前引用并添加相关信号池的引用,这同样适用于hardware2。 现在为了避免这种手动工作,我想自动化这个过程要么在XML上声明一个变量并访问csproj文件中的变量来决定在编译/运行时访问哪个变量。
目前为了避免这个问题,我有一个单独的exe,它读取xml并决定将它们复制到一个公共文件夹中。这个exe将在我们项目中的prebuild事件时被调用。
//信号池1文件
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SignalPool { public abstract class SignalPool { public abstract string PreExec(); public abstract string PostExec(); public abstract string VnVExec(); public static string HWVar1 = "HWVar1"; public static string HWVar2 = "HWVar2"; public static string HWVar3 = "HWVar3"; public static string HWVar4 = "HWVar4"; }
}
//信号池2
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SignalPool { public abstract class SignalPool { public abstract string PreExec(); public abstract string PostExec(); public abstract string VnVExec(); public static string HWVar1 = "HWVar5"; public static string HWVar2 = "HWVar6"; public static string HWVar3 = "HWVar7"; public static string HWVar4 = "HWVar8"; } }
//访问池变量
主文件
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Linq; namespace TestLibraries { class Program { static void Main(string[] args) { AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; Testhardware th = new Testhardware(); th.functionToValues(); } private static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { if (args.Name.Contains("SignalPool")) //Put in the name of your assembly { //var configValue = XDocument.Parse("type1").Document.Descendants("hardware").First().Value; var configValue = XDocument.Load(@"C:\Users\ha23031\Documents\Visual Studio 2010\Projects\TestLibraries\TestLibraries\TestInfo.xml").Document.Descendants("IsRealHMI").First().Value; if (configValue == "false") { return System.Reflection.Assembly.LoadFile(@"C:\Users\ha23031\Documents\Visual Studio 2010\Projects\TestLibraries\SignalPool\bin\Debug\SignalPool.dll"); } else if (configValue == "true") { return System.Reflection.Assembly.LoadFile(@"C:\Users\ha23031\Documents\Visual Studio 2010\Projects\SignalPool\bin\Debug\SignalPool.dll"); } } return null; } }
}
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace TestLibraries { class Testhardware : SignalPool.SignalPool { public override string PostExec() { return string.Empty; } public override string PreExec() { return string.Empty; } public override string VnVExec() { return string.Empty; } public string functionToValues() { // This is how i access variables based on the loaded variables string s = SignalPool.SignalPool.HWVar1; return string.Empty; } } }
“我可以在文本文件中声明一个变量,说明type1并在我的csproj文件中导入该文本文件,并为我的应用程序分配适当的引用吗?”
这不正是我在您链接到的博客文章中描述的内容吗?
在我从.csproj文件加载的配置文件‘ProjectReferences.txt’中查找已定义的变量’ SomeProject ‘。
ProjectReferences.txt
..\SomeProject
.csproj文件
{6CA7AB2C-2D8D-422A-9FD4-2992BE62720A} SomeProject ..\Libraries\SomeProject.dll
在.Net为您加载之前,您需要在应用程序启动期间加载正确的DLL。 只要创建该类的实例,NET就会加载默认DLL。 因此,请确保在访问属性之前先加载正确的DLL。 确保您不会在初始类中访问这些属性,因为.Net将加载它。
像这样的东西:
class Program { static void Main(string[] args) { //var configValue = XDocument.Parse("type1 ").Document.Descendants("hardware").First().Value; var configValue = XDocument.Load("MyXmlConfig.xml").Document.Descendants("hardware").First().Value; if (configValue == "type1") { System.Reflection.Assembly.LoadFile(@"C:\TEMP\MyAssembly_Type1.dll"); } else if (configValue == "type2") { System.Reflection.Assembly.LoadFile(@"C:\TEMP\MyAssembly_Type2.dll"); } MyRepositoryClass.Initialize(); } } static class MyRepositoryClass { public static void Initialize() { var variable1 = MyAssembly.MyRepository.Variable1; var variable2 = MyAssembly.MyRepository.Variable2; var variable3 = MyAssembly.MyRepository.Variable3; } }
替代加载DLL按需(当.Net要求它时):
class Program { static void Main(string[] args) { AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; MyRepositoryClass.Initialize(); } private static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { if (args.Name.Contains("MyAssembly")) //Put in the name of your assembly { //var configValue = XDocument.Parse("type1 ").Document.Descendants("hardware").First().Value; var configValue = XDocument.Load("MyXmlConfig.xml").Document.Descendants("hardware").First().Value; if (configValue == "type1") { return System.Reflection.Assembly.LoadFile(@"C:\TEMP\MyAssembly_Type1.dll"); } else if (configValue == "type2") { return System.Reflection.Assembly.LoadFile(@"C:\TEMP\MyAssembly_Type2.dll"); } } return null; } }