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?
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...
}