title: How to implement Setter Dependency Injection on internal Access Modifiers
body: <p>I have a .NET assembly that I’m building and I want only a few classes and methods to be visible to the end user. I’m creating  the assembly with a library class project in framework 4.5 with Visual Studio 2015.
  The assembly will provide a control console of sorts to manage some interrelated backend services and applications. Most of the work will happen within the assembly, and will be invisible to the end user.
  Most of the classes in the assembly’s namespace will be internal and so invisible to the end user; but the assembly will provide a few public classes and methods that the end user can interact with.
  The way I envision it, the assembly will provide a public static class where the end user will pass in the parameters needed by the assembly, and then return an object that the end user can utilize.
  For example, here is a pseudocode template of what that public static class might look conceptually  like.</p>
  
  <pre><code>public static class ControlClientStarter
  {
      public static ISrvcManagerConsole GetSrvcManagerConsole(/*. all the parameters . */)
      {
          // Some code that parses the parameters . . . 
  
          ISrvc_Controller accountController = new AccountSrvc_Controller( /*. . . */ );
          ISrvc_Controller contractController = new ContractSrvc_Controller( /*. . . */ );
          ISrvc_Controller imageController = new ImageSrvc_Controller( /*. . . */ );
          ICatalogApp_Controller calatlogController = new CatalogApp_Controller( /*. . . */ );
          IPortal_Controller portalController = new PortalSrvc_Controller( /*. . . */ );
  
          ISrvcManagerConsole srvcMngrConsole = new SrvceManagerConsole(
              accountController,
              contractController,
              imageController,
              calatlogController,
              portalController);
  
          return srvcMngrConsole;
      }
  }
  </code></pre>
  
  <p>The code above demonstrates that the assembly .dll provides a public static class called ControlClientStarter which has one public static method called GetSrvcManagerConsole() ( . . .).
  That static method accepts several parameters, and then based on those parameters and various logic, creates objects that implement the ISrvc_Controller interface as well as other objects that implement other interfaces. 
  Those objects are injected into the constructor of the srvcMngrConsole object and returns that to the end user.</p>
  
  <p>The end user would access the control console with something conceptually similar to this,</p>
  
  <pre><code>ISrvcManagerConsole clientMngrConsole = ControlClientStarter.GetSrvcManagerConsole(  /*. . . */ );
  clientMngrConsole.DoThis(  /*. . . */ );
  clientMngrConsole.StopThis(  /*. . . */ );
  clientMngrConsole.GetThat(  /*. . . */ );
  clientMngrConsole.PublishThat(  /*. . . */ );
  </code></pre>
  
  <p>The inside of the control console might look something abstractly like this pseudocode where the arguments passed into the SrvcManagerConsole get saved to interface implementing fields within the srvcMngrConsole object,</p>
  
  <pre><code>internal class SrvcManagerConsole : ISrvcManagerConsole
  {
      ISrvc_Controller accountController ;
      ISrvc_Controller contractController ;
      ISrvc_Controller imageController ;
      ICatalogApp_Controller calatlogController;
      IPortal_Controller portalController ;
  
      internal SrvcManagerConsole(
          ISrvc_Controller accountController,
          ISrvc_Controller contractController,
          ISrvc_Controller imageController,
          ICatalogApp_Controller calatlogController,
          IPortal_Controller portalController)            
      {
          this.accountController = accountController;
          this.contractController = contractController;
          this.imageController = imageController;
          this.calatlogController = calatlogController;
          this.portalController = portalController;
      }
  
      public void DoThis( /*. . . */ )
      {  /*. . . */ }
      public void StopThis( /*. . . */ )
      {  /*. . . */ }
      public void GetThat( /*. . . */ )
      {  /*. . . */ }
      public void PublishThat( /*. . . */ )
      {  /*. . . */ }
  
      // private and-or internal methods and properties . . . 
  }
  </code></pre>
  
  <p>As you can see, I’m using a constructor dependency injection to avoid tight-coupling; but there is a problem with that. What if in the future I want to add a MapPublishApp_Controller, a VideoSrvc_Controller, and so on?</p>
  
  <p>If I add them to the constructor after the first release, then other code that already uses this assembly will also have to change.
  If I add another SrvceManagerConsole  constructor with additional parameters that take the new controllers, then I won’t be breaking previous code, but the constructor parameters will start to get too numerous.
  Also, depending on the parameters that the end user sends to the GetSrvcManagerConsole() method of the ControlClientStarter class, I might not want to use all of the controllers. It would be much better if I could have methods that add the controllers to the fields. 
  The challenge is that I wouldn’t want the end user to be able to access those fields. I only want the assembly to instantiate the controller classes and assign the hidden fields. If I give those those assignment methods in the SrvceManagerConsole class internal access modifiers, then the GetSrvcManagerConsole() method can’t see them because it is public.</p>
  
  <p>Note the access modifiers on the interfaces. The only one that is public is the one that is implemented by the SrvcManagerConsole class. The rest are internal because they should not be accessible to the end user.</p>
  
  <pre><code>internal interface ISrvc_Controller { /*. . . */ }
  internal interface ICatalogApp_Controller { /*. . . */ }
  internal interface IPortal_Controller { /*. . . */ }
  
  public interface ISrvcManagerConsole
  {
      void DoThis( /*. . . */ );
      void StopThis( /*. . . */ );
      void GetThat( /*. . . */ );
      void PublishThat( /*. . . */ );
  }
  </code></pre>
  
  <p>Those methods above like PublishThat() will use the fields that got set to the objects injected into the constructor. The end-user programmer that uses my assembly will never see those interface implementing instances. The clientMngrConsole object created by the end user programmer will use those internal objects without the programmer even knowing how they’re used.</p>
  
  <p>The classes that implement interfaces with internal access modifiers would abstractly be something like this,</p>
  
  <pre><code>class AccountSrvc_Controller : ISrvc_Controller { /*. . . */ }
  class ContractSrvc_Controller : ISrvc_Controller { /*. . . */ }
  class ImageSrvc_Controller : ISrvc_Controller { /*. . . */ }
  class CatalogApp_Controller : ICatalogApp_Controller { /*. . . */ }
  class PortalSrvc_Controller : IPortal_Controller { /*. . . */ }
  </code></pre>
  
  <p>There might be more controller classes in the future, maybe not.
  I’ve been unable to figure out how to assign the controller classes to back end fields in a way that those fields will be inaccessible to the end user while maintaining some level of loose coupling incase the implementation of those controllers needs to change in the future.
  I have discovered, however, that if the other methods and properties are stated in the ISrvceManagerConsole interface, and that interface is set with a public modifier, those methods and properties in the SrvceManagerConsole class that implements that interface can also be set as public and successfully accessed despite the SrvceManagerConsole class itself being set as "internal."
  I tried property setter injection, but C# (wisely) does not support a property with an interface backend (because that wouldn’t make any sense).
  Another possibility is to have the SrvceManagerConsole constructor take one parameter which wraps all the other interface instances in a dictionary perhaps. I haven’t tried that yet.
  I can’t be the first person to have confronted this. There must be a common solution that I’ve been unable to locate.
  I know that the industry standard is to use IoC containers for what I’m doing above, but that’s not going to be done here.
  I’ve never tried an architecture like this before. I know that this is probably not the best architecture; but for now it doesn’t have to be exactly according to some overly complex architecture. I’m going for an adequate design as I’m learning more about this.</p>
  
  <p><strong>Edit # 1, why the Builder pattern doesn’t work here</strong></p>
  
  <p>Suppose I try to avoid the constructor anti-pattern by using a builder pattern like the pseudocode below.</p>
  
  <p>Imagine that the SrvcManagerConsole looks like this:</p>
  
  <pre><code>internal class SrvcManagerConsole : ISrvcManagerConsole
  {
      internal ISrvc_Controller accountController;
  
      internal SrvcManagerConsole() { }
  
      internal void AddAccountController(ISrvc_Controller accountController)
      {
          this.accountController = accountController;
      }
  }
  </code></pre>
  
  <p>Imagine I change the ControlClientStarter to something like this:</p>
  
  <pre><code>public static class ControlClientStarter
  {
      public static ISrvcManagerConsole GetSrvcManagerConsole(/*. all the parameters . */)
      {
          Federated_ControlBuilder fedBuilder  = new Federated_ControlBuilder();
          ISrvcManagerConsole srvcMngrConsole = fedBuilder.GetSrvcManagerConsole();
          return srvcMngrConsole;
      }
  }
  </code></pre>
  
  <p>And then I implement the Federated_ControlBuilder like this:</p>
  
  <pre><code>internal class Federated_ControlBuilder : IControl_Builder
  {
      internal ISrvcManagerConsole srvcMngrConsole;
  
      internal Federated_ControlBuilder()
      {
          srvcMngrConsole = new SrvcManagerConsole();
      }
  
      public void InjectAccountController(ISrvc_Controller accountController)
      {
          // The srvcMngrConsole object can not see the InjectAccountController method.
          // srvcMngrConsole.
      }
  
      internal ISrvcManagerConsole GetSrvcManagerConsole()
      {
          return srvcMngrConsole;
      }
  }
  </code></pre>
  
  <p>The InjectAccountController(…) method of the Federated_ControlBuilder class can’t see the AddAccountController(…) method of the SrvcManagerConsole class because it is internal.</p>
  
  <p>The sticking point of my question is not how to avoid a constructor anti- pattern in and of itself; but rather the challenge is to avoid the anti-pattern while making certain classes and methods in an assembly inaccessible to the end user programmer, hence, the use of the word “<strong>internal</strong>” title of the question, “How to implement Setter Dependency Injection on <strong>internal</strong> Access Modifiers.”</p>
  
  <p>If it were merely a question of avoiding a constructor anti-pattern, I could have made the fields of the SrvcManagerConsole public and added to them directly through the GetSrvcManagerConsole(…) method of the ControlClientStarter class.</p>