title: Cache the DTO or cache data from the expensive resource
body: <p>I have a WebService that returns a DTO.  The webservice gets the data to populate the DTO from an expensive resource.  In this simple example, several WebService methods may hit the same ExpensiveResourceProvider method.  Where is the best place to perform caching to maximize cache hits?  At the webservice or at the ExpensiveResourceProvider?  I should note that some data from the ExpensiveResourceProvider changes quite often and should not be cached for long.</p>
  
  <pre><code>public class MyWebService : System.Web.Services.WebService
  {
      public MyDTO GetObject1And2()
      {
          MyDTO dto12 = HttpRuntime.Cache.Get("dto12") as MyDTO;
          if(dto12 == null){
              dto12 = new MyDTO();
              dto12.Object1 = ExpensiveResourceProvider.GetObject1();
              dto12.Object2 = ExpensiveResourceProvider.GetObject2();
              HttpRuntime.Cache.Insert("dto12", dto12);
          }
          return dto12;
      }
      public MyDTO GetObject2And3()
      {
          MyDTO dto23 = HttpRuntime.Cache.Get("dto23") as MyDTO;
          if (dto23 == null)
          {
              dto23 = new MyDTO();
              dto23.Object2 = ExpensiveResourceProvider.GetObject2();
              dto23.Object3 = ExpensiveResourceProvider.GetObject3();
              HttpRuntime.Cache.Insert("dto23", dto23);
          }
          return dto23;
      }
      public MyDTO GetObject1And3()
      {
          MyDTO dto13 = HttpRuntime.Cache.Get("dto13") as MyDTO;
          if (dto13 == null)
          {
              dto13 = new MyDTO();
              dto13.Object1 = ExpensiveResourceProvider.GetObject1();
              dto13.Object3 = ExpensiveResourceProvider.GetObject3();
              HttpRuntime.Cache.Insert("dto13", dto13);
          }
          return dto13;
      }
  }    
  public class ExpensiveResourceProvider
  {
      public static object GetObject1() 
      {
          object obj1 = HttpRuntime.Cache.Get("object1") as object;
          if(obj1 == null){
              obj1 = new object();
              HttpRuntime.Cache.Insert("object1", obj1);
          }
          return obj1; 
      }
      public static object GetObject2() 
      {
          object obj2 = HttpRuntime.Cache.Get("object2") as object;
          if (obj2 == null)
          {
              obj2 = new object();
              HttpRuntime.Cache.Insert("object2", obj2);
          }
          return obj2;
      }
      public static object GetObject3()
      {
          object obj3 = HttpRuntime.Cache.Get("object3") as object;
          if (obj3 == null)
          {
              obj3 = new object();
              HttpRuntime.Cache.Insert("object3", obj3);
          }
          return obj3;
      }
  }
  public class MyDTO
  {
      public object Object1 { get; set; }
      public object Object2 { get; set; }
      public object Object3 { get; set; }
  }
  </code></pre>