Search code examples
c#windows-phone-8mvvmasync-awaitmvvmcross

Running multiple tasks in one Service's method


It is a good practice to have a simple methods, which returns tasks:

public class MessageService : IMessageService
{
    public Task<IEnumerable<Message>> DownloadMessagesTask()
    {
         return MyWebClient.GetMessages();
    }

Now, I'd like to add a caching to the local storage:

    public Task<bool> WriteMessagesTask(IEnumerable<Message> list)
    {
        return MyIsoStorageManager.Write(list);
    }
    // same for reading

Most naive way is to call them from viewmodel:

    public async void Init()
    {
         var result = await messageService.ReadMessagesTask();
         if (result == null)
         {
             MessagesList = await messageService.DownloadMessagesTask();
             var writingResult = await messageService.WriteMessagesTask(MessagesList);
         }

But how can I store this logic in a service, just to avoid code repeating in another viewmodels? Or should I keep service clean and call tasks in a viewmodel?


Solution

  • Expose one method from your service that wraps what you now have in you async void Init() and call it from VM. You could also extract interface and inject that in your viewmodel (via constructor or property).

    META

    public class MyViewModel
    {
        public MyViewModel()
            :this(new Service())
        {}
    
        public MyViewModel(IService service)
        {
            Service = service;
            Initialize();
        }
    
        public IService Service { get; set; }
    
        private async void Initialize()
        {
            // Fire forget
            await Service.DoSomething();
        }
    }
    

    META

    public interface IService
    {
        // change if you need to return something
        Task DoSomething();
    }
    
    public Service : IService
    {
        public async Task DoSomething()
        {
            var result = await ReadMessagesAsync();
            if (result == null)
            {
                var messages = await DownloadMessagesAsync();
                await WriteMessagesAsync(messages);
            }
        }
    
        // private read/write/download methods here...
    }