locked
Lazy Loading a model RRS feed

  • Question

  • I have a WCF Service that returns a model. The model contains a large chunk of data that isn't going to be user very often and I would like to load it only when needed, ie, lazy loading.

     

    So for an example, lets say I have an email message. The DataContract might look something like this:

    Code Snippet

    [DataContract]

    public class Email

    {

    [DataMember]

    public string Sender;

     

    [DataMember]

    public string Subject;

     

    [DataMember]

    public string Message;

    }

     

     

    And here is what the service looks like:

    Code Snippet

    [ServiceContract]

    interface IEmailService

    {

    [OperationContract]

    Email GetEmail();

     

    [OperationContract]

    string GetMessage();

    }

     

     

    Now, how would I go about making Message lazy loaded? My first attempt looked like this:

    Code Snippet

    [DataContract]

    public class Email

    {

    [DataMember]

    private IEmailService eservice;

    public Email(IEmailService service)

    {

    eservice = service;

    }

     

    [DataMember]

    public string Sender;

     

    [DataMember]

    public string Subject;

     

    private string _Message;

    public string Message

    {

    get

    {

    if (_Message == null)

    {

    _Message = eservice.GetMessage();

    }

    return _Message;

    }

    }

    }

     

     

    Basically, when I create the Email object, I construct it with a reference to the service, which is a "this" reference. Then I was hoping that through some magic, WCF would return the service and I could call it from the client. Unfortunately, that doesn't work because I think the service can't be serialized and returned (I assume). How should I go about implementing lazy loading?

     

    The other option is to create another set of objects on the client side (or as another library) that contains all the lazy loading. However, I much prefer to keep the code with the service. That way, a client can simply update the service reference in visual studio and have the latest models.

     

    Any suggestions on this?

    Tuesday, August 12, 2008 7:08 PM

Answers

  • There is no out of the box way do to this because the object is serialized down.  What you need to do is break up the object.  So you could have GetEmail and GetEmailMessage.  the GetEmailMessage method would take in an ID that would be obtained from GetEmail.  You could abstract this away in the client like you described.

    Tuesday, August 12, 2008 8:17 PM
  • Thanks Dan. I ended up going with a slightly different solution. I know this is sort of a dead thread, but I felt I should give some follow-up on what I did for a solution.

     

    Basically, I broke the service's interface and the models out into a seperate project that the client and server applications can reference. This project also contains a singleton that is the service to use to lazy load.

     

    The basic concept from this can be found here:

    http://www.thoughtshapes.com/WCF/ExampleTwo.htm

     

    By seperating out the interfaces/models into a seperate project, a model can be shared rather then generated. Because the model is shared, you can provide lazy-loading implementation details. But, out-of-the-box, you're right, there is no way.

     

    Thanks,

    Daniel

    Monday, August 18, 2008 2:51 PM

All replies

  • There is no out of the box way do to this because the object is serialized down.  What you need to do is break up the object.  So you could have GetEmail and GetEmailMessage.  the GetEmailMessage method would take in an ID that would be obtained from GetEmail.  You could abstract this away in the client like you described.

    Tuesday, August 12, 2008 8:17 PM
  • Thanks Dan. I ended up going with a slightly different solution. I know this is sort of a dead thread, but I felt I should give some follow-up on what I did for a solution.

     

    Basically, I broke the service's interface and the models out into a seperate project that the client and server applications can reference. This project also contains a singleton that is the service to use to lazy load.

     

    The basic concept from this can be found here:

    http://www.thoughtshapes.com/WCF/ExampleTwo.htm

     

    By seperating out the interfaces/models into a seperate project, a model can be shared rather then generated. Because the model is shared, you can provide lazy-loading implementation details. But, out-of-the-box, you're right, there is no way.

     

    Thanks,

    Daniel

    Monday, August 18, 2008 2:51 PM
  • Daniel,

    I'm having the same problem with WCF and lazy loading for my domain model.  I tried to use the link that you posted but it doesn't work.  Would you post another link with the example or send it to me by email? My mail is fernando.delfino@gmail.com

    Thanks,
    Fernando
    Saturday, October 18, 2008 5:37 PM