title: Implementing a generic factory method
body: <p>I've implemented a Vehicle service that is responsible for servicing vehicles such as cars and trucks:</p>
  
  <pre><code>public interface IVehicleService
  {
      void ServiceVehicle(Vehicle vehicle);   
  }
  
  public class CarService : IVehicleService
  {
      void ServiceVehicle(Vehicle vehicle)
      {
          if (!(vehicle is Car))
              throw new Exception("This service only services cars")
  
         //logic to service the car goes here
      }
  }
  </code></pre>
  
  <p>I also have a vehicle service factory that is responsible for creating a vehicle service according to the type of vehicle passed in to the factory method:</p>
  
  <pre><code>public class VehicleServiceFactory 
  {
      public IVehicleService GetVehicleService(Vehicle vehicle)
      {
          if (vehicle is Car)
          {
              return new CarService();
          }
  
          if (vehicle is Truck)
          {
              return new TruckService();
          }
  
          throw new NotSupportedException("Vehicle not supported");
      }
  }
  </code></pre>
  
  <p>The issue I had was with the <code>CarService.ServiceVehicle</code> method. It's accepting a <code>Vehicle</code> when ideally it should accept a <code>Car</code>, as it knows that it will only service cars. So I decided to update this implementation to use generics instead:</p>
  
  <pre><code>public interface IVehicleService&lt;T&gt; where T : Vehicle
  {
      void ServiceVehicle(T vehicle); 
  }
  
  public class CarService : IVehicleService&lt;Car&gt;
  {
      void ServiceVehicle(Car vehicle)
      {
          //this is better as we no longer need to check if vehicle is a car
  
          //logic to service the car goes here 
      }
  }
  
  public class VehicleServiceFactory 
  {
      public IVehicleService&lt;T&gt; GetVehicleService&lt;T&gt;(T vehicle) where T : Vehicle
      {
          if (vehicle is Car)
          {
              return new CarService() as IVehicleService&lt;T&gt;;
          }
  
          if (vehicle is Truck)
          {
              return new TruckService() as IVehicleService&lt;T&gt;;
          }
  
          throw new NotSupportedException("Vehicle not supported");
      }
  }
  </code></pre>
  
  <p>The issue I currently have is when calling this factory as follows:</p>
  
  <pre><code>var factory = new VehicleServiceFactory();
  Vehicle vehicle = GetVehicle();
  var vehicleService = factory.GetVehicleService(vehicle);  // this returns null!
  vehicleService.ServiceVehicle(vehicle);
  </code></pre>
  
  <p><code>GetVehicleService</code> returns <code>null</code>, I guess because I'm passing in the base type <code>Vehicle</code> into this method, so <code>T</code> would evaluate to <code>Vehicle</code> and it isn't possible to cast from <code>CarService</code> (which implements <code>IVehicleService&lt;Car&gt;</code>) to the effective return type which would be <code>IVehicleService&lt;Vehicle&gt;</code> (please correct me if I'm wrong).</p>
  
  <p>Would appreciate some guidance on how to resolve this.</p>