3

When implementing the facade pattern in Java, I can easily hide the subsystem of the facade by using the package-private modifier. As a result, there is only a small interface accessible from outside the facade/package, other classes of the sub-system are not visible.

As you already know, there is no package-private modifier in C#, but a similar one called internal. According to the docs, classes defined as internal are only accessible within the same assembly.

From what I unterstand, I have to create at least two assemblies (means practically two .exe/.dll files) in order to hide the subsystem of the facade physically. By physically I mean that the classes a) cannot be instantiated from outside and b) are not shown by intellisense outside the facade.

  1. Do I really have to split my small project into one .exe and one .dll (for the facade) so that the internal keyword has an effect? My facade's subsystem only consists of 2 classes, an own .dll seems to be overkill.
  2. If yes, what is the best practice way in Visual Studio to outsource my facade to its own assembly?

Don't get me wrong, I have no real need to split up my program into several assemblies. I just want to hide some classes behind my facade from IntelliSense and prevent instantiation from outside. But if I'm not wrong, there is no easier way that that.

alapeno
  • 2,724
  • 6
  • 36
  • 53
  • One of the ideas behind the facade pattern, as I understand it, is to give a simple interface to clients needing simple functionality but still have the full advanced functionality of the subsystem available to more advanced clients. Why then, would you want to hide the subsystem? – FishBasketGordo Oct 11 '12 at 20:08
  • Okay, my question wasn't good, forget about the facade pattern. I just want to hide a few classes. Or let's say I want to turn my facade into an encapsulated component. – alapeno Oct 11 '12 at 20:11
  • An assembly can grant access to its internals to other assemblies via "friend assemblies" via the `InternalsVisibleToAttribute`. But, it's unclear what you're really trying to accomplish so I don't know if that would help in any way. – Peter Ritchie Oct 11 '12 at 20:22
  • You could use nested classes. http://stackoverflow.com/questions/1083032/why-would-i-ever-need-to-use-c-sharp-nested-classes – Tejas Sharma Oct 11 '12 at 20:23
  • Usually a facade sits in front of as you said a complex system. I'm not sure two classes would count as complex. But I definitely see the benefits of Package/Namespace private members. That's pretty awesome. – Michael Brown Oct 11 '12 at 20:39

1 Answers1

3

Using a separate project is the general preferred approach. In fact, you often have interfaces or facades in a third assembly that both the implementation and UI assemblies reference.

That said, you can accomplish this in a single assembly using a nested private subclass.

public interface IMyService {}

public static class MyServiceBuilder
{
    public static IMyService GetMyService()
    {
        //Most likely your real implementation has the service stored somewhere
        return new MyService();
    }

    private sealed class MyService : IMyService
    {
        //...
    }
}

The outer class effectively becomes your 'package' for privacy scoping purposes. You probably wouldn't want to do this for large 'packages'; in those cases, it's cleaner to move the code to a separate assembly and use internal.

Note that if you primary objection to multiple assemblies is deployment, you can actually merge multiple assemblies for the purpose of creating a simpler executable or library deployment. This way you can retain the insulation benefits of multiple projects/assemblies without having the headache of multiple files that can potentially be distributed or versioned independently.

Dan Bryant
  • 27,329
  • 4
  • 56
  • 102
  • I've always been curios, does merging assemblies affect the internal keyword? That is, do objects and methods that were previously unavailable (due to separate assemblies) suddenly become available? – Erik Funkenbusch Oct 11 '12 at 20:26
  • @Mystere Man, you still have multiple assemblies loaded by the CLR. It's just a bootloader trick to allow the multiple assemblies to be pulled from a single file rather than multiple files. – Dan Bryant Oct 11 '12 at 21:01