views:

90

answers:

3

I have an internal API that I would like others to reference in their projects as a compiled 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. 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. 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. 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. I'm also completely open to a whole new approach to solve the problem if that's what it takes.

A: 

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. Wrong approach, I would say.

TomTom
+1 for the config file! But you can only take a const for that.
chriszero
Yeah, the conditional compile was an "oh, dammit, duh" moment when I realized I was heading down that path.I'll look into reflection, not afraid to go that route if that's what it takes.It's my understanding that the strings that populate attributes have to be consts - as in, can't be read from the config file at run-time, hence the conditional switching. Would love to be wrong on that point, though.
Chris
+6  A: 

You don't need to do this. Those URLs are not "real" URLs - they do not represent locations on the Internet. They are only used to make names unique.

You should use the same namespace name for dev as for production.

John Saunders
Must they match the namespaces of the service methods on the service it's calling?
Chris
No, they don't have to, but they can. It's all about making names unambiguous. If you had operation (method) names that were the same as type names, then you'd want to use different namespaces so that namespace+localname are unique.
John Saunders
Excellent, thank you for the guidance - I think I'll wander down this path first and eliminate my ignorance of XML namespaces in the first place. Couldn't hurt one way or the other!
Chris
Thus far complaining about not being able to recognize the HTTP SOAPAction with the namespace I arbitrarily gave it, but still hacking at it.
Chris
+1  A: 

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 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 :)

Artiom Chilaru