Many applications need to store data related to the application. If you're building applications for multiple platforms the APIs for storage is different.
Following five storage types is the most common ones:
Storage to store application data locally on the device.
Storage to store application data in the cloud, for example OneDrive or iCloud. Data that is saved in the cloud could be accessible from different devices.
Storage to use when caching data. Platforms that have a separate storage for cache data will not contain cache storage in the backup, WinRT for an example. Cached data is not necessary to have in a backup, it will be cached again after restore of the backup.
Storage to store application settings locally on the device.
Remote settings storage
Storage to store application settings in the cloud, for example OneDrive or iCloud. Settings will be synced for all devices you have installed the application on.
You can handle storage in different ways, one strategy is to create one interface for each of the storage types above, for example ILocalStorage and IRemoteStorage. Every interface will have an implementation for each platform. With help of an IoC-container (Inversion of Control) we can use the interface to call platform specific code from shared code.
public interface ILocalStorage
Task AddAsync(string key, object value);
Task<T> GetAsync(string key, object value);
Task<bool> ContainsAsync(string key);
Task RemoveAsync(string key);
One other strategy is to create one storage interface, IStorage and have a method with storage type as an argument. As with the first strategy each platform will have a platform specific implementation that can be used from shared code with help of IoC.
public enum StorageTypes
public interface IStorage
Task AddAsync(string key, object value, StorageTypes storageType);
Task<T> GetAsync(string key, object value, StorageTypes storageType);
Task<bool> ContainsAsync(string key, StorageTypes storageType);
Task RemoveAsync(string key, StorageTypes storageType);
public class Storage : IStorage
public async Task AddAsync(string key, object value, StorageTypes storageType)
//code for local storage
//code for remote storage
//code for cache storage
//code for settings storage
//code for remote settings storage
I prefer the first strategy beacause I like small classes with one role, the maintainability will be much higher and you can make changes to one implementation without the risk of breaking other functionality than that one you want to change.
As an example, one platform maybe don't have CacheStorage, then the LocalStorage and CacheStorage will be pretty much the same. But if that platform will get CacheStorage in the future you can change the implementation of ICacheStorage without touching the working code for LocalStorage.