EmbeddedDude EmbeddedDude - 1 month ago 10
C# Question

Conditional access modifiers?

My company has a software product with a very large sized DLL (approx 11 MB) and I have been assigned the task to reduce its size by making two or three versions of the DLL to only allow provided lists of methods in each DLL. The current DLL has every method but most of our clients only use certain sets of methods depending on their industry.

I have the solution with 7 projects in it: two are C++ projects, and five are C#. Two of the C# projects call functions from C++ projects (using dllexport), I think it's called unmanaged code (please bear with me, I am a novice in this field so I don't know the terminology too well - in fact I just now found out that "public/private/protected/etc" are called "Access Modifiers"! :-) )

So far I have figured out how to define a solution-wide preprocessor constant to use with "#if". So far I have come up with the following to create three DLL:

For example, something like the following is in one of the .cs files:

#if DLL_FOR_INDUSTRY_A
public void method_A(int arg1)
#else
private void method_A(int arg1)
#endif
{
for (int x=0; x<arg1; x++)
{
// code here;
}
}

#if DLL_FOR_INDUSTRY_B
public void method_B(int arg1)
#else
private void method_B(int arg1)
#endif
{
// code here;
}

#if DLL_FOR_INDUSTRY_C
public void method_C(int arg1)
#else
private void method_C(int arg1)
#endif
{
// code here;
}


But my problem is that I have around 400+ methods in the entire DLL! Some methods will be common among new DLLs that I am supposed to create. Two of the new DLLs will represent software editions (think of it as "Standard" vs "Professional" editions.) I also looked at using "[System.Diagnostics.Conditional]" but it doesn't work if a method is "public method_A(int x)" instead of something like "public void method_A(int x)". If I add "void" in existing methods, it breaks a lot of other calls (nightmare!) Plus I'm not an expert in this field so I can't tell which way would be the better approach.

My question- does anyone have a better suggestion on how I should be doing this properly? Even better if someone can point me to the right direction on how such large DLL can be "conditionally" compiled so that I can set a preprocessor constant to change the DLL outcome. (I tried compiling with what I showed above (only covering around 15 methods instead of 400+, its a lot of work) but the DLL size didn't seem to change, not sure if unused methods are still getting compiled into the new DLL.)

Can Access modifiers be made "Conditional" in an easier way? (so that they don't show up in the output DLL.)

Please help! I am using Visual Studio 2015 on Windows 7 & Windows 10.
My sincere gratitude to anyone that can give me some direction, I have been at this for the past 5 days including the weekend and yet I have no good solution. :-(

Answer

I suggest using inheritance here rather than conditional compilation - for example, having a base class that holds common functionality used by all industries and implementations for different industries that contains industry-specific functionality. You can then split it up into multiple assemblies, giving everyone a DLL with the common functionality along with a second DLL that contains the code relevant to their particular industry.

You definitely do not want to do a lot of "if" statements to do the industry-specific stuff. I remember working for a company about 10 years ago that had code like

if (client == x) ...
else if (client == y) ...
else ...

Predictably, this quickly became very difficult to maintain. For the record, the code was written before I got there, so it wasn't my fault ;). In their case, they could've benefited from using the Template Method Pattern instead of doing client-specific reasoning. (The Strategy Pattern and Factory Pattern are both often very helpful in cases like this).