tags:

views:

59

answers:

4

I want to release a DLL that contains some classes for other developers to use. Behind these classes are another DLL that contatain referenced functionality. In the development environment I want this backend DLL to have development oriented functions, but when the code is migrated to the production environment, I want that backend DLL to be the real one. What is the best way to switch that backend DLL?

Thank you for any help.

A: 

Using a .config file to store the name of the assembly you want to run and when empty/missing load the backend version. [more] It easiest to do this with an another assembly that contains interfaces that are shared.

kenny
Could you point me to an example of how to do this? Thank you again.
Sako73
I have been experimenting, and it appears that as long as I define the same classes, and the DLL names stay the same, physically changing the DLL in the directory works fine. Do you know of any problems with, or downfalls of this approach?
Sako73
One way is to use an IOC tool like Autofac http://code.google.com/p/autofac/. Another is to use Assembly.Load or as described in this link http://stackoverflow.com/questions/370286/c-interface-call-method-in-different-project-assembly
kenny
A: 

Try marking your "Developer Only" classes with the ConditionalAttribute. Such as:

[Conditional("DEBUG")]
public class DeveloperClass
{
    // ...
}

You an also mark methods this way. It is a little bit cleaner than using #if/#endif. This way you can have all your source code shared, but change which ones you build simply by using the Solution Configuration.

Nick
The issue appears to be that using that attribute will call or not call the method, but will not change the method itself. However the #if/#else/#endif does appear to work, and will allow only one set of code files.
Sako73
A: 

So I assume that both your 'development' dll and 'production' dll have the same interface?

If so then just have a Wrapper over the dll and the Wrapper will wrap all the functions in the dll (the interface being the same for both versions of the dll).

Use the following code to load the library,

if(PRODUCTION) {
        target_lib = "productionlib.dll";
} else {
        target_lib =  "developmentlib.dll";
}
lib = LoadLibrary(target_lib);

The Wrapper will just forward the function calls to the corresponding loaded library (either production or development library as described above)

functionptr=(LPFunctionType)GetProcAddress(lib,"TargetFunction");
if(functionptr) { functionptr(bs); }
Santhosh
A: 

Following on from your comment:

I have been experimenting, and it appears that as long as I define the same classes, and the DLL names stay the same, physically changing the DLL in the directory works fine. Do you know of any problems with, or downfalls of this approach?

The main problem/downfall of this approach is ensuring that you keep the classes/methods exposed by both DLLs in lock-step. Probably the best way to do this, given that you seem to have a model of:

PROGRAM -> REFERENCED DLL -> [One of two "Backend DLL's]

Would be to create abstract classes/interfaces in "REFERENCED DLL" that specify the classes/methods that both of the "Backend DLL'" should expose, then have both backend DLL's reference the "REFERENCED DLL" and implement actual classes on-top of the abstract classes/interfaces.

For example, "Program" expects to be able to use a class called "Logger" in REFERENCED.DLL, which uses methods in the clas called "BackEndLogger" in BACKEND.DLL (whether that be the development or production version). So, in REFERENCED.DLL have a class such as:

public abstract class BackEndLogger
{
    public virtual void LogEvent(string eventToLog)
}

Then, in both versions of "BACKEND.DLL", have a class such as:

public class Logger : BackEndLogger
{
    public override void LogEvent(string eventToLog)
    {
    ... code for implementation goes here
    }
}

REFERENCED.DLL will have a reference to a DLL called "BACKEND.DLL", and, because the classes interfaces are exactly the same (pretty much ensured by keeping them in synch by implementing the abstract classes/interfaces in REFERENCED.DLL) will be none the wiser.

Hopefully this made some sort of sense =)

Rob