You are on page 1of 9

4/10/2015 IDeliverable 

­ LazyField<T>

LazyField<T>
orchard (/Tags/orchard)

LazyField<T> is a utility class that lives in the

Orchard.ContentManagement.Utilities namespace and enables

you to return a value in a lazy manner.It's public members are:

public members are:

class LazyField<T> {
    T Value { get; set; }
    void Loader(Func<T, T> loader);
    void Setter(Func<T, T> setter);
}

If LazyField is used without configuring a loader and / or setter delegate, it will simply act as a
backing field.

When to use it
Sometimes, when developing content parts, you may come across the need to load related data,
for example one or more content items.
Or perhaps you want to expose a service from your content part, or implement a computed
property that requires some service class.

Because you cannot inject dependencies into content parts using the constructor, you will have
to do so manually.
For example, you could write a content handler and handle the Activated event to manually set
some properties on the activated content item.
Although that would work, this means that on each request and when each content item is
activated, the related data is loaded. This may impact the performance negatively.
So instead, you will want to load the related data in a lazy manner.
http://www.ideliverable.com/blog/lazyfield­t 1/9
4/10/2015 IDeliverable ­ LazyField&lt;T&gt;

How to use it 


In order to implement a lazy field, you will have to do two things:

1. Create a public or internal member on your class (for example your own content part) of
type LazyField<T>, where T is the type of the object to be loaded in a lazy manner. 
2. Configure the lazy field member by providing a getter and optionally a setter delegate.

For example, imagine we have a part called


CustomerPart<CustomerPartRecord>. CustomerPartRecord has a property called
InvoiceAddressId of type int, which is stores the id of an Address content item.
The part and record classes look like this:

public class CustomerPart : ContentPart<CustomerPartRecord> {
    
}

public class CustomerPartRecord : ContentPartRecord {
    public virtual int InvoiceAddressId { get; set; }
}

public class AddressPart : ContentPart { }

Note that I didn't create the InvoiceAddressId property on the CustomerPart. Although I could
have done so, what I want to do instead is create a property called InvoiceAddress of type
Address.
This enables use to access the related Address content item without having to use the
ContentManager ourselves everytime we need to load it. Also, the LazyField<T> instance will
hold a reference to the loaded object, so we don't have to worry about loading the Address
multipel times during the same request.

Let's start by implementing the lazy field as the backing store and a property that leverages the
field: 

http://www.ideliverable.com/blog/lazyfield­t 2/9
4/10/2015 IDeliverable ­ LazyField&lt;T&gt;

public class CustomerPart : ContentPart<CustomerPartRecord> {
   
   // Define the lazy field that will act as the backing store for the Address content item
.
   // Note that we defined it as a internal because we need to access this field from the o
utside
   // in order to configure the setter and getter.
   internal readonly LazyField<AddressPart> InvoiceAddressField = new LazyField<AddressPart
>();

   // Define a property that provides access to the lazy field value
   public AddressPart InvoiceAdddress {
      get { return InvoiceAddressField.Value; }
      set { InvoiceAddress.Value = value; }
}

Now that we have the lazy field in place, the next thing we need to do is configure it as soon as
our CustomerPart is loaded / activated.
We'll do this from a content handler:

public class CustomerPartHandler : ContentPartHandler {

   private IContentManager _contentManager;

   public CustomerHandler( IContentManager contentManager ){
      _contentManager = contentManager;
      OnActivated<CustomerPart>(SetupCustomerPart);
   }
   
   private void SetupCustomerPart(ActivatedContentContext context, CustomerPart part){
      
         // Setup the getter of the lazy field
         part.InvoiceAddressField.Loader( addressPart => _contentManager.Get<AddressPart>(p
art.Record.InvoiceAddressId));

        // Setup the setter of the lazy field
        part.InvoiceAddressField.Setter( addressPart => {
        part.Record.InvoiceAddressId = addressPart != null ? addressPart.Id : 0;
        return addressPart;
     });
   }
}

http://www.ideliverable.com/blog/lazyfield­t 3/9
4/10/2015 IDeliverable ­ LazyField&lt;T&gt;

Essentially, we are passing in a delegate to the loader that in turn uses the injected
ContentManager to load the Address item when the LazyField is first accessed.
The setter delegate simply gets the ID of the specified Address item and stores it in the record's
InvoiceAddressId property.

Alternative approach
In the previous example, we showed how to use LazyField<T> to load related content using the
ContentManager. The primary reasons to use the LazyField were:

1. To load the related content using a service class (ContentManager) in a lazy manner
2. To load the related content only once, on first access.

However, because all content parts have access to the ContentItem of which they're part of, we
actually do have access to the ContentManager from within our part.
So alternatively, we could have implemented the InvoiceAddress property as follows:

public class CustomerPart : ContentPart<CustomerPartRecord> {
   
   private AddressPart _invoiceAddress;

   public AddressPart InvoiceAdddress {
      get { return _invoiceAddress ?? (_invoiceAddress = ContentItem.ContentManager.Get<Add
ressPart>(Record.InvoiceAddressId)); }
      set { 
         _invoiceAddress = value;
         Record.InvoiceAddressId = value != null ? value.Id : 0;
      }
}

This code will work as well and doesn't require configuring a LazyField from the content handler.
However, I think this is less elegant than the LazyField approach, since we now have data access
logic inside of the content part.

Source code
Download source code: https://lazyfielddemo.codeplex.com/releases/view/95579
(https://lazyfielddemo.codeplex.com/releases/view/95579)

Related Articles
http://www.ideliverable.com/blog/lazyfield­t 4/9
4/10/2015 IDeliverable ­ LazyField&lt;T&gt;

Tutorial: Content Part Editors (/orchard-development/content-part-editors)

 11/18/2014 09:31 PM by Sipke Schoorstra (/blog/author/sipke)

5 comments
SciencApp 10/01/2012 09:19 AM

Can you please send us a practical implementation of this idea. Something


simple and working, a module. Or images of the outcomes etc....

Sipke Schoorstra 10/02/2012 04:59 AM [http://www.ideliverable.com]


(http://www.ideliverable.com)

The post has been updated with a link to a sample module. If you install this
module you should see a working demo where you will be able to create
customers and addresses: https://lazyfielddemo.codeplex...
(https://lazyfielddemo.codeplex.com/releases/view/95579)

Ali 01/09/2013 06:58 PM

This was very helpful, great post. Thanks,

I am however stuck on how to get associated Fields from a LazyFiled of


Content Part, For instance I have added an image filed to the user part. How
do I access that. any Ideas ?

Michael 11/07/2014 07:56 AM

http://www.ideliverable.com/blog/lazyfield­t 5/9
4/10/2015 IDeliverable ­ LazyField&lt;T&gt;

Just a heads up on this that caught me out. When you resolve the namespace
for LazyField in your containing part, make sure it resolves to
Orchard.ContentManagement.Utilities.LazyField and not
Orchard.Core.Common.Utilities.LazyField. This is a very similar class except
for a different in the number of params in the Loader() func. I wonder why
they both exist?

Rob 11/07/2014 07:56 AM

This was my problem too, maybe the author (who has done a wonderful job)
could put something in the main article about this, I was struggling until I
finally looked in comments.

Leave a comment
Name:

Enter your name

Email address:

Enter your email address

Not displayed on the site, used to obtain Gravatar image.

URL:

Enter your website URL

Comment:

How to Format

http://www.ideliverable.com/blog/lazyfield­t 6/9
4/10/2015 IDeliverable ­ LazyField&lt;T&gt;

Type the text
Privacy & Terms
(http://www.google.com/intl/en/policies/)

Submit

 Subscribe to IDeliverable Blog (RSS)


(/rss?containerid=32)

 Subscribe (email) (/subscribe)

Topics
autofac (1) (/Tags/autofac) azure (2) (/Tags/azure) cloud services (2) (/Tags/cloud%20services)

codemirror (1) (/Tags/codemirror) globalization (1) (/Tags/globalization) jquery (1) (/Tags/jquery)

knockoutjs (1) (/Tags/knockoutjs) linqjs (1) (/Tags/linqjs) orchard (33) (/Tags/orchard)

orchard harvest (1) (/Tags/orchard%20harvest) performance (2) (/Tags/performance)

powershell (2) (/Tags/powershell) ssl (1) (/Tags/ssl) startup tasks (2) (/Tags/startup%20tasks)

webapi (1) (/Tags/webapi)

Authors

http://www.ideliverable.com/blog/lazyfield­t 7/9
4/10/2015 IDeliverable ­ LazyField&lt;T&gt;

Daniel Stolt (/blog/author/daniel)


Daniel is the go-to guy here at IDeliverable for all things Azure. He
blogs about his experiences developing for the cloud.

(/blog/author/daniel)

Sipke Schoorstra (/blog/author/sipke)


Sipke is the resident Orchard CMS specialist here at IDeliverable. He
blogs about site building and module development.

(/blog/author/sipke)

Archive
2014 2013 2012
November (6) December (2) October (1)
(/blog/archive/2014/11) (/blog/archive/2013/12) (/blog/archive/2012/10)
September (3) June (5) September (3)
(/blog/archive/2014/9) (/blog/archive/2013/6) (/blog/archive/2012/9)
March (9) August (1)
(/blog/archive/2013/3) (/blog/archive/2012/8)
January (1) April (7)
(/blog/archive/2013/1) (/blog/archive/2012/4)
February (4)
(/blog/archive/2012/2)
January (18)
(/blog/archive/2012/1)

http://www.ideliverable.com/blog/lazyfield­t 8/9
4/10/2015 IDeliverable ­ LazyField&lt;T&gt;

Postal address:
IDeliverable, Ltd.
PO Box 58341
3733 Limassol
CYPRUS

Visiting address:
IDeliverable, Ltd.
Sotiri Tofini 4, 2nd floor
Agios Athanasios
4102 Limassol
CYPRUS

VAT number: CY10318155U


TIC number: 12318155W
info@ideliverable.com (mailto:info@ideliverable.com)
http://www.ideliverable.com (http://www.ideliverable.com)

All information on this website copyright © 2015 by IDeliverable, Ltd.

http://www.ideliverable.com/blog/lazyfield­t 9/9

You might also like