1

I have a function that sets 2 lists within a class to pull from a third party.
I put it in one function because going to the third party takes time and I only want to have to do it once for this page. This is my class:

public class MyClass
{
    public IEnumerable<dynamic> ListOne { get; set; }
    public IEnumerable<dynamic> ListTwo { get; set; }
}

This is my function that sets & returns the lists

public MyClass GetLists()
    {
            //Here I have the code that connects to the third party etc 
            //Here set the items.. from the third party 
             MyClass _MyClass = new MyClass();
            _MyClass.ListOne = ThirdParty.ListOne;
             _MyClass.ListTwo = ThirdParty.ListTwo;
            return (_MyClass);
        };
    }

So, now in my web API I have 2 functions - one that returns each list.

    [Route("ListOne")]
    public IHttpActionResult GetListOne()
        {
        IEnumerable<dynamic> ListOne = GetLists().ListOne;
        return Json(ListOne);
        }

    [Route("ListTwo")]
    public IHttpActionResult GetListTwo()
        {
        IEnumerable<dynamic> ListTwo = GetLists().ListTwo;
        return Json(ListTwo);
        }

My problem is that each time I call the webApi getListone or getListTwo, the function will run again and call the third party. How can I prevent this?

Thank you!

Raktim Biswas
  • 4,011
  • 5
  • 27
  • 32
shw
  • 135
  • 3
  • 12

1 Answers1

1

Put the data retrieving logic in the property and lazy-load the data, i.e. load it the first time the property is called.

private IEnumerable<dynamic> _listOne;
public IEnumerable<dynamic> ListOne {
    get {
        if (_listOne == null) {
            // Retrieve the data here. Of course you can just call a method of a
            // more complex logic that you have implemented somewhere else here.
            _listOne = ThirdParty.ListOne ?? Enumerable.Empty<dynamic>();
        }
        return _listOne;
    }
}

?? Enumerable.Empty<T>() ensures that null will never be returned. Instead an empty enumeration will be returned.

See: ?? Operator (C# Reference) and
        Enumerable.Empty Method ()

Have also a look at the Lazy<T> Class.

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
  • Thank you for your reply. I have 2 questions a)I thought that I'm not supposed to put a lot of code in the property itself? (it's quite a bit of code to connect to the third party) b) what if my ThirdParty.listOne happens to return null, it will then execute again, no? – shw Aug 21 '16 at 17:50
  • You can put the main data retrieving logic somewhere else and just call this logic from the property. – Olivier Jacot-Descombes Aug 21 '16 at 17:52
  • I thought properties are not supposed to call things like database calls based on this post: http://stackoverflow.com/questions/6682902/why-should-a-c-sharp-property-getter-not-read-from-a-db – shw Aug 21 '16 at 18:14
  • @shw: See [Logic inside class properties setters & getters](http://programmers.stackexchange.com/questions/225354/logic-inside-class-properties-setters-getters) and [How Much Logic in Getters](http://programmers.stackexchange.com/questions/126721/how-much-logic-in-getters). – Olivier Jacot-Descombes Aug 21 '16 at 18:21
  • See also Eric Lippert's blog [Fabulous adventures in coding: When should I write a property?](https://ericlippert.com/2014/05/19/when-should-i-write-a-property/). – Olivier Jacot-Descombes Aug 21 '16 at 18:32
  • I'm reading these links that you posted and I'm really getting a better understanding. Thank you – shw Aug 22 '16 at 10:44