简体   繁体   中英

One DLL with two implementations for two applications

I have a DLL with some classes and methods. And two applications using it. One admin-application that needs almost every method and a client-application that only needs parts of the stuff. But big parts of it are used by both of them. Now I want make a DLL with the admin stuff and one with the client stuff.

  1. Duplicating the DLL and edit things manually everytime is horrible.
  2. Maybe conditional compiling helps me but I dont know how to compile the DLL twice with different coditions in one solution with the three projects.

Is there a better approach for this issue than having two different DLLs and manually editing on every change?

In general, you probably don't want admin code exposed on the client side. Since it's a DLL, that code is just waiting to be exploited, because those methods are, by necessity, public. Not to mention decompiling a .NET DLL is trivial and may expose inner-workings of your admin program you really don't want a non-administrator to see.

The best, though not necessarily the "easiest" thing to do, if you want to minimize code duplication, is to have 3 DLLs:

  1. A common library that contains ONLY functions that BOTH applications use
  2. A library that ONLY the admin application will use (or else compile it straight into the application if nothing else uses those functions at all)
  3. A library that ONLY the client application will use (with same caveat as above)

A project that consists of a server, client, and admin client should likely have 3-4 libraries:

  1. Common library, used by all 3
  2. Client library, used by client and server
  3. Admin library, used by server and admin client
  4. Server library, used only by server (or else compile the methods directly into the application)

Have you considered using dependency injection on the common library, some form of constructor injection to determine the rules that need to be applied during execution.

Here's a very simple example:

public interface IWorkerRule
    {
        string FormatText(string input);
    }

    internal class AdminRules : IWorkerRule
    {
        public string FormatText(string input)
        {
            return input.Replace("!", "?");
        }
    }

    internal class UserRules : IWorkerRule
    {
        public string FormatText(string input)
        {
            return input.Replace("!", ".");
        }
    }

    public class Worker
    {
        private IWorkerRule Rule { get; set; }

        public Worker(IWorkerRule rule)
        {
            Rule = rule;
        }

        public string FormatText(string text)
        {
            //generic shared formatting applied to any consumer
            text = text.Replace("@", "*");

            //here we apply the injected logic 
            text = Rule.FormatText(text);
            return text;
        }
    }

    class Program
    {       
        //injecting admin functions
        static void Main()
        {
            const string sampleText = "This message is @Important@ please do something about it!";

            //inject the admin rules.
            var worker = new Worker(new AdminRules());
            Console.WriteLine(worker.FormatText(sampleText));

            //inject the user rules
            worker = new Worker(new UserRules());
            Console.WriteLine(worker.FormatText(sampleText));

            Console.ReadLine();

        }

    }

When run you'll produce this output.

This message is *Important* please do something about it?

This message is *Important* please do something about it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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