title: Create a wrapper around a third party dll to abstract the dll and to be able to unit test my code
body: <p>I have been assigned to help out on a legacy system; this system has a reference to a third party library throughout the application(more than 2000 times). There isn’t a single unit test within the application and this is a mission critical system.</p>
  
  <p>What I would like to do is refactor the code so that the third party classes are not referenced throughout all the application. I would also like to introduce unit test around the code I can control.</p>
  
  <p>one example of the code that uses the 3rd party dll looks like the following (3rd party classes are Controller and Tag):</p>
  
  <pre><code>public class Processor
  {
      private Controller _clx;
      private Tag _tag;
  
      public bool Connect(string ip, string slot, int timeout, bool blockWrites, string tagName)
      {
          _clx = new Controller(ip, slot, timeout);
          if (_clx != null)
          {
              _clx.Connect();
              if (_clx.IsConnected)
              {
                  if (tagName != null)
                  {
                      _tag = new Tag(_clx, tagName, ATOMIC.DINT);
                      return ((_tag.ErrorCode == 0) &amp;&amp; _tag.Controller.IsConnected);
                  }
  
                  _tag = new Tag {Controller = _clx, DataType = ATOMIC.DINT, Length = 1};
                  return (_tag.Controller.IsConnected);
  
              }
          }
          return false;
      }
  }
  </code></pre>
  
  <p>I have been able to create a wrapper class that helped me to remove all references of the 3rd party  dll, now all calls go through my wrapper and my wrapper is the only code that calls the 3rd party dll.</p>
  
  <pre><code> public class ControllerWrapper 
  {
      public ControllerWrapper(string ip, string slot, int timeout)
      {
          Controller = new Controller(ip,slot,timeout);
      }
      public Controller Controller { get; set; }
  }
  
  public class TagWrapper
  {
      public Tag Tag { get; set; }
      public TagWrapper()
      {
      }
      public TagWrapper(ControllerWrapper clx, string tagName, ATOMIC datatype)
      {
          Tag = new Tag(clx.Controller, tagName,datatype);
  
      }
  }
  </code></pre>
  
  <p>And now my Processor class looks like:</p>
  
  <pre><code>public class Processor
  {
      private ControllerWrapper _clx;
      private TagWrapper _tag;
      public bool Connect(string ip, string slot, int timeout, bool blockWrites, string tagName)
      {
          _clx = new ControllerWrapper(ip, slot, timeout);
          if (_clx != null)
          {
              _clx.Controller.Connect();
              if (_clx.Controller.IsConnected)
              {
                  if (tagName != null)
                  {
                      _tag = new TagWrapper(_clx, tagName, ATOMIC.DINT);
                      return ((_tag.Tag.ErrorCode == 0) &amp;&amp; _tag.Tag.Controller.IsConnected);
                  }
                  _tag = new TagWrapper {Tag = {Controller = _clx.Controller, DataType = ATOMIC.DINT, Length = 1}};
                  return (_tag.Tag.Controller.IsConnected);
              }
          }
          return false;
      }
  }
  </code></pre>
  
  <p>My problem is that I still am unable to unit test the Processor.Connect(...)</p>
  
  <p>Additional info -- </p>
  
  <ul>
  <li>This is a winforms app .NET 2.0.</li>
  <li>There isn't any DI or IOC tools used.</li>
  <li>The concrete Tag object requires a concrete Controller object.</li>
  <li>The 3rd party dll cannot be used in the test environment because it uses the IP and tries to connect to the controller.</li>
  </ul>
  
  <p>I think what I am not understanding is how to get the creation of the tag and the controller out of the Connect method so that I can have a Fake Tag and Fake Controller in a unit test, but have the real Tag and Controller in the production code.</p>
  
  <p>I have been playing with this for about 4 days now and implemented many different versions, but still am at a loss.</p>
  
  <p>I have tried a builder class like the following:</p>
  
  <pre><code>public static class TagBuilder
  {
      public static ITagProxy BuildTag()
      {
          return new TagProxy().CreateTag();
      }
  
      public static ITagProxy BuildTag(IControllerProxy clx, string tagName, ATOMIC datatype)
      {
          return new TagProxy().CreateTag(clx, tagName, datatype);
      }
  }
  </code></pre>
  
  <p>With a ITagProxy something like</p>
  
  <pre><code>public interface ITagProxy
  {
      Tag Tag { get; set; }
  
      ITagProxy CreateTag();
      ITagProxy CreateTag(IControllerProxy clx, string tagName, ATOMIC dataType);
  }
  </code></pre>
  
  <p>and ControllerProxy like:</p>
  
  <pre><code>public interface IControllerProxy
  {
      Controller Controller { get; set; }
      IControllerProxy CreateController(string ip, string slot, int timeout );
  }
  </code></pre>
  
  <p>Now the processor code looks like:</p>
  
  <pre><code> public class Processor
  {
      private IControllerProxy _clx;
      private ITagProxy _tag;
  
      public virtual bool Connect(string ip, string slot, int timeout, bool blockWrites, string tagName)
      {
          _clx = CreateController(ip, slot, timeout);
          if (_clx != null &amp;&amp; _clx.Controller != null)
          {
              _clx.Controller.Connect();
  
              if (_clx.Controller.IsConnected)
              {
                  // check this connection carefully, if it fails the controller is not in the slot configured
                  if (tagName != null)
                  {
                      // use supplied Tag Name to to a qualified connection
                      _tag = TagBuilder.BuildTag(_clx, tagName, ATOMIC.DINT);
  
                      return ((_tag.Tag.ErrorCode == 0) &amp;&amp; _tag.Tag.Controller.IsConnected);
                  }
                  _tag = TagBuilder.BuildTag();
                  _tag.Tag.Controller = _clx.Controller;
                  _tag.Tag.Length = 1;
  
                      return (_tag.Tag.Controller.IsConnected);
              }
          }
          return false;
      }
      public virtual IControllerProxy CreateController(string ip, string slot, int timeout)
      {
          if (_clx == null)
              _clx = new ControllerProxy();
          return _clx.CreateController(ip, slot, timeout);
      }
  }
  </code></pre>
  
  <p>But it is still dependent on the concrete Tag and Controller.</p>
  
  <p>How can I get the code to not be dependent on the Concrete Tag and Controller?</p>