开发者

switch DLL based on environment - .net

开发者 https://www.devze.com 2022-12-17 16:28 出处:网络
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 environm

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.


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


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.


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.


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); }
0

精彩评论

暂无评论...
验证码 换一张
取 消