LazyField<T>

What is it

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:

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.

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: 

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 outside
   // 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>(part.Record.InvoiceAddressId));

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

 

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<AddressPart>(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

Related Articles

Tutorial: Content Part Editors

Tags: LazyField

48 Comments

  • SciencApp said

    <p>Can you please send us a practical implementation of this idea. Something simple and working, a module. Or images of the outcomes etc....</p>

  • Sipke Schoorstra said

    <p>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: <a href="https://lazyfielddemo.codeplex.com/releases/view/95579" rel="nofollow">https://lazyfielddemo.codeplex...</a></p>

  • Ali said

    <p>This was very helpful, great post. Thanks, </p>

    <p> 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 ?</p>

  • Internet Coupons said

    Hey! Do you know if they make any plugins to help with SEO?
    I'm trying to get my blog to rank for some targeted keywords but I'm not seeing very
    good success. If you know of any please share.
    Appreciate it!

  • Shaun said

    Hey there fantastic website! Does running a blog such as this
    require a large amount of work? I've no understanding of coding but I was hoping to start my own blog in the near future. Anyways, if you have any ideas or tips for new blog owners please share. I understand this is off subject however I simply had to ask. Appreciate it!

  • Get Writing Job said

    I really love your website.. Excellent colors &
    theme. Did you develop this amazing site yourself?
    Please reply back as I'm looking to create my own blog and want to know where you got this from or what the theme is called. Thank you!

  • Nona said

    Excellent goods from you, man. I've be aware your stuff prior to and you are just too great. I actually like what you have bought right here, really like what you're saying and the way wherein you say it.
    You make it entertaining and you continue to take care of to keep it sensible.

    I can't wait to learn much more from you. This is really a tremendous site.

  • Michael said

    <p>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?</p>

  • www.linkedin.com said

    Hmm it looks like your blog ate my first comment (it was super long) so I guess I'll just sum it up what I wrote and say, I'm thoroughly
    enjoying your blog. I as well am an aspiring blog blogger but I'm still new to everything. Do you have any suggestions for first-time blog writers? I'd genuinely appreciate it.

  • トリーバーチ said

    First off I would like to say great blog!
    I had a quick question which I'd like to ask if you do not mind. I was curious to know how you center yourself and clear your head prior to writing. I've
    had a difficult time clearing my thoughts in getting my thoughts out.
    I do take pleasure in writing but it just seems like the first 10 to 15 minutes tend to be lost just trying to figure out how
    to begin. Any ideas or tips? Thank you!

  • Discount Christian Louboutin outlet said

    Application classic bright red welcome screen, and guide users to explore the interactive parts of six kinds of different characteristics. Cheap Christian louboutin outlet,Users can browse the latest quarterly series, one at a time to enjoy all kinds of shoes and handbags, you can also share it with friends via Facebook, twitter, or email, and the product can be added to your collection.
    [url=http://www.healthymindscanada.ca/cms/redsole.asp]Discount Christian Louboutin outlet[/url]

  • カシオ 電波時計 said

    Hi there! I know this is somewhat off topic but I was wondering which blog platform are you using for this site? I'm getting fed up of Wordpress because I've had problems with hackers and I'm looking at alternatives for another platform. I would be fantastic if you could point me in the direction of a good platform.
    カシオ 電波時計 http://casio.draefern.com/

  • フォーマル said

    Howdy this is kind of of off topic but I was wanting to know if blogs use WYSIWYG editors or if you have to manually code with HTML. I'm starting a blog soon but have no coding skills so I wanted to get advice from someone with experience. Any help would be enormously appreciated!
    フォーマル http://suit.hamishgibson.com/specials.html

  • nike sb said

    Currently it appears like Expression Engine is the top blogging platform available right now. (from what I've read) Is that what you are using on your blog?
    nike sb http://nike.prostaiq.com/nike-sb-japan-4.html

  • メンズ スーツ said

    My programmer is trying to convince me to move to .net from PHP. I have always disliked the idea because of the costs. But he's tryiong none the less. I've been using WordPress on a number of websites for about a year and am concerned about switching to another platform. I have heard excellent things about blogengine.net. Is there a way I can import all my wordpress content into it? Any help would be greatly appreciated!
    メンズ スーツ http://www.infohamil.com/ビジネス-japan-7.html

  • ワークブーツ said

    Hi are using Wordpress for your blog platform? I'm new to the blog world but I'm trying to get started and create my own. Do you require any html coding knowledge to make your own blog? Any help would be really appreciated!
    ワークブーツ http://boots.fenyastravels.com/チペワ-japan-7.html

  • ノーカラージャケット said

    Hmm it looks like your site ate my first comment (it was super long) so I guess I'll just sum it up what I submitted and say, I'm thoroughly enjoying your blog. I too am an aspiring blog blogger but I'm still new to everything. Do you have any tips for inexperienced blog writers? I'd certainly appreciate it.
    ノーカラージャケット http://www.abrilpage.com/ジャケット-japan-3.html

  • ugg boots outlet said

    Hello,I check your new stuff named "Skywalker Software Development - LazyField<T>" daily.Your up the good work! And you can look our website aboot ugg boots outlet

  • www.zrw.cn/scripts/index.aspx said

    1、一天,某高尔夫俱乐部的球迷打完一场很糟糕的球,匆匆离开会所,准备打道回府。在路上,警察拦住他,问:“二十分钟前是你在第8洞开球的吗?”“是的。”高尔夫球迷答道。“你打了一个左曲线球,结果球不巧飞过树丛,飞出了球场,是吗?”“是啊,没错。你怎么知道的?”警察严肃地说:“你打出的球飞到高速公路上,砸穿了一位司机的挡风玻璃。车子失去控制,撞了另外五辆车和一辆救火车。救火车没能赶到火场,结果失火的大楼被烧成了平地。说吧,你打算怎么办?”球迷仔细想了想,答道:“我想我的站姿要再收紧点儿,握杆再紧些,右手大拇指再放低些。”2、公交车上,一名男子靠着车窗,悠闲地抽完一支香烟,一挥手,烟头划出一道火红的弧线,以一种优美的姿态飞出窗外。两秒钟后,一辆疾驶而来的出租车突然转了方向,一头扎进路边的绿化带。半个月后,一家工厂发生了火灾,上千万元的资产顷刻化为乌有。一个月后,当初扔烟头的男子戒烟了。因为他失业了。失业的原因是,他所在的工厂破产了。工厂破产的原因是,半个月前一场大火把工厂烧了个精光。工厂失火的原因是,一个月前请来的对工厂消防设施进行改造的工程师出了车祸。工程师出车祸的原因是,他乘坐的出租车突然冲进了绿化带。出租车冲进绿化带的原因是,有一个燃着的烟头突然落入了司机的衣领。生活中的讽刺小幽默
    www.zrw.cn/scripts/index.aspx http://www.zrw.cn/scripts/index.aspx

  • como reconquistar said

    I don't even know the way I stopped up here, however I thought this publish was once good. I don't know who you are however definitely you're going to a famous blogger should you aren't already. Cheers!

  • avicii vip tickets price said

    When you apply for a loan at an internet cash advance website the facts are
    immediately sent to the financial institution avicii vip tickets price this has not only helped inside the empowerment with the women,
    but has additionally provided them using a facility to generate an outside identity of these own.

  • Rob said

    <p>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.</p>

  • league of legends hacks youtube said

    I absolutely love your blog and find the majority of your post's to be what precisely
    I'm looking for. can you offer guest writers to write content for
    yourself? I wouldn't mind writing a post or elaborating on some of the subjects you write concerning here.
    Again, awesome weblog!

  • how to grow taller said

    I'm curious to find out what blog system you're utilizing?
    I'm experiencing some small security problems with my latest website and I'd
    like to find something more risk-free. Do you have any suggestions?

  • home furniture said

    Clean and Sand - When the perfect day arrives, you will
    need to remove any hardware you do not want painted and clean your
    laminate furniture off with TSP and a rag. For unique seating,
    a swing is a perfect place to rest. So choosing the right furniture for
    your home or office can sometimes be a difficult task.

  • Zoe said

    But wanna remark on few general things, The website pattern is perfect, the written content is really fantastic. “To establish oneself in the world, one has to do all one can to appear established.” by Francois de La Rochefoucauld.

  • Free Hacks Cheats Download said

    Itss like youu read mʏ mind! Yoou ɑppear tto ҝnow so mucɦ aabout tɦis, liҝe you wtote thee bbook іn it
    oг something. I tҺink tɦat yоu cann do ѡith ome pucs tо drive tҺe message
    ɦome ɑ littlе bit, Ьut іnstead of tɦаt, this iss wonderful blog.
    A gfeat read. Ι'll definitеly bbe bаck.

  • China Information on Wikipedia said

    It's appropriate time to make some plans for the future and it is time to bee happy.

    I've read this post and if I could I want to suggest you some interesting things or tips.
    Perhaps you can write next articles referring to this article.
    I wish to read more things about it!

  • cheap air jordans said

    Excellent posting! We, as well began workboxes the past 1 week of faculty recently because I merely didn't want to delay. My partner and i submitted right now on my blog about these, too! Such a amazing strategy, also it looks like it works intended for many kinds of homeschool mums!
    cheap air jordans http://www.survocom.com/jordans.php

  • clash of clans triche said

    I'm really impressed with your writing skills as well
    as with the layout on your blog. Is this a paid theme or did you modify it
    yourself? Anyway keep up the nice quality writing, it is rare to see a great blog like this one nowadays.

  • nike air max cheap said

    Excellent beat ! I would like to apprentice whilst you amend your website,
    how could i subscribe for a weblog web site? The account aided me a
    appropriate deal. I have been a little bit familiar of this your broadcast provided shiny clear concept

  • christian louboutin heels cheap said

    Hello there, You've done an incredible job.
    I will certainly digg it and personally recommend to my friends.

    I'm confident they'll be benefited from this website.

Add a Comment