简体   繁体   English

C#中的条件编译黑客-是否有办法实现这一目标?

[英]Conditional compilation hackery in C# - is there a way to pull this off?

I have an internal API that I would like others to reference in their projects as a compiled DLL. 我有一个内部API,我希望其他人在他们的项目中以编译的DLL引用。 When it's a standalone project that's referenced, I use conditional compilation (#if statements) to switch behavior of a key web service class depending on compilation symbols. 当引用的是一个独立项目时,我将使用条件编译(#if语句)根据编译符号来切换关键Web服务类的行为。 The problem is, once an assembly is generated, it appears that it's locked into whatever the compilation symbols were when it was originally compiled - for instance, if this assembly is compiled with DEBUG and is referenced by another project, even if the other project is built as RELEASE, the assembly still acts as if it was in DEBUG as it doesn't need recompilation. 问题是,一旦生成了程序集,它似乎就被锁定在最初编译时的任何编译符号中,例如,如果此程序集是用DEBUG编译的并且被另一个项目引用,即使另一个项目是作为RELEASE构建,由于不需要重新编译,程序集仍然像在DEBUG中一样工作。 That makes sense, just giving some background. 这是有道理的,只是提供一些背景知识。

Now I'm trying to work around that so I can switch the assembly's behavior by some other means, such as scanning the app/web config file for a switch. 现在,我正在尝试解决此问题,以便可以通过其他方法来切换程序集的行为,例如扫描app / web配置文件中的开关。 The problem is, some of the assembly's code I was switching between are attributes on methods, for example: 问题是,我在其中切换的某些程序集代码是方法的属性,例如:

#if PRODUCTION
        [SoapDocumentMethodAttribute("https://prodServer/Service_Test", RequestNamespace = "https://prodServer", ResponseNamespace = "https://prodServer")]
#else
        [SoapDocumentMethodAttribute("https://devServer/Service_Test", RequestNamespace = "https://devServer", ResponseNamespace = "https://devServer")]
#endif
        public string Service_Test()
        {
            // test service
        }

Though there might be some syntactical sugar that allows me to flip between two attributes of the same type in another fashion, I don't know it. 尽管可能有一些语法上的糖可以让我以另一种方式在相同类型的两个属性之间切换,但我不知道。 Any ideas? 有任何想法吗?

The alternative method would be to reference the entire project instead of the assembly, but I'd rather stick with just referencing the compiled DLL if I can. 另一种方法是引用整个项目而不是程序集,但我更愿意只引用编译后的DLL。 I'm also completely open to a whole new approach to solve the problem if that's what it takes. 如果需要的话,我也完全愿意采用全新的方法来解决问题。

You don't need to do this. 您不需要这样做。 Those URLs are not "real" URLs - they do not represent locations on the Internet. 这些URL不是“真实” URL,它们不代表Internet上的位置。 They are only used to make names unique. 它们仅用于使名称唯一。

You should use the same namespace name for dev as for production. 您应该为开发使用与生产相同的名称空间名称。

The thing is, the #if statements are ran against only during compilation.. Once you have a compiled assembly - it's going to stick with what it had.. The rest of the code is stripped out from the assembly :) 问题是,仅在编译期间才使用#if语句。.一旦有了已编译的程序集,它将与原来的程序保持一致。.其余代码将从程序集中删除:)

If you want the URLs to be different for your test/production, you should create a new attribute, that derives from SoapDocumentMethodAttribute , and sets these values depending on your AppSetting values :) 如果您希望测试/生产的URL不同,则应创建一个新的属性,该属性派生自SoapDocumentMethodAttribute ,并根据您的AppSetting值设置这些值:)

Well, ok - first, OBVIOUSLY a conditional COMPILE stays in place after the compile. 好吧,好的-首先,显然条件编译在编译后仍然存在。 How the heck did you get the idea it was otherwise? 您是怎么想的呢? It is a conditional COMPILE. 这是一个有条件的编译。

Attributes yo ucan fix with reflection - you can "override" reflection to return your own information there. 您可以使用反射修复属性-您可以“覆盖”反射以在此处返回您自己的信息。 It iws tricky, but it is possible (same way you can "inject" properties into reflection code). 它看起来很棘手,但是有可能(用同样的方式将属性“注入”到反射代码中)。 Not sure I would like that to happen, though. 不过,我不确定我是否希望这样。 Basically... you should get something like a server URL not from reflection but from the config file. 基本上...您应该从服务器而非配置文件中获得类似服务器URL的内容。 Wrong approach, I would say. 我会说方法错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM