Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can i use Lazy<T> in an ASP.NET MVC Controller?

I've got a simple ASP.NET MVC controller. Inside a few action methods, I access a resource which I'll say is expensive.

So I thought, why not make it static. So instead of doing double checked locking I thought I can leverage the use of Lazy<T> in .NET 4.0. Call the expensive service once instead of multiple times.

So, if this is my pseduo code, how can I change it do use Lazy<T>. For this contrite example, I'll use the File System as the expensive resource So with this example, instead of getting all the files from the destination path, every time a request calls that ActionMethod, I was hoping to use Lazy to hold that list of files .. which of course, makes the call the first time only.

Next assumption: don't worry if the content is changed. That's out of scope, here.

public class FooController : Controller
{
    private readonly IFoo _foo;
    public FooController(IFoo foo)
    {
        _foo = foo;
    }

    public ActionResult PewPew()
    {
        // Grab all the files in a folder.
        // nb. _foo.PathToFiles = "/Content/Images/Harro"
        var files = Directory.GetFiles(Server.MapPath(_foo.PathToFiles));

        // Note: No, I wouldn't return all the files but a concerete view model
        //       with only the data from a File object, I require.
        return View(files);
    }
}
like image 822
Pure.Krome Avatar asked Sep 21 '11 02:09

Pure.Krome


People also ask

Can you explain lazy loading in C#?

Lazy Loading is a technique that delays the initialization of an object. This is a new feature of C# 4.0. The basic idea of lazy loading is to load objects or data only when they are needed. A lazy loading pattern is also called Object on Demand.

What is lazy loading in ASP NET MVC?

Lazy loading is delaying the loading of related data, until you specifically request for it. It is the opposite of eager loading. For example, the Student entity contains the StudentAddress entity.

What is lazy loading in Entity Framework?

Lazy loading is the process whereby an entity or collection of entities is automatically loaded from the database the first time that a property referring to the entity/entities is accessed. Lazy loading means delaying the loading of related data, until you specifically request for it.


2 Answers

In your example, the result of Directory.GetFiles depends on the value of _foo, which is not static. Therefore you cannot use a static instance of Lazy<string[]> as a shared cache between all instances of your controller.

The ConcurrentDictionary<TKey, TValue> sounds like something that is closer to what you want.

// Code not tested, blah blah blah...
public class FooController : Controller
{
    private static readonly ConcurrentDictionary<string, string[]> _cache
        = new ConcurrentDictionary<string, string[]>();

    private readonly IFoo _foo;
    public FooController(IFoo foo)
    {
        _foo = foo;
    }

    public ActionResult PewPew()
    {
        var files = _cache.GetOrAdd(Server.MapPath(_foo.PathToFiles), path => {
            return Directory.GetFiles(path);
        });

        return View(files);
    }
}
like image 145
Greg Avatar answered Oct 06 '22 00:10

Greg


I agree with Greg that Lazy<> is inappropriate here.

You could try using asp.net caching to cache the contents of a folder, using _foo.PathToFiles as your key. This has an advantage over Lazy<> that you can control the lifetime of the caching so it will refetch the contents say every day or every week without requiring an application restart.

Also caching is friendly to your server in that it will gracefully degrade if there is not enough memory to support it.

like image 29
Martin Capodici Avatar answered Oct 06 '22 01:10

Martin Capodici