I cache the data and use local database in my Windows Phone app. The algorithm is very simple:
- Get data from DB and show in UI
- Get data from a web service and show in UI
- Update data in DB from the web service
Some data need to be saved in DB, and some do not need to.
For these purposes, I have the following classes.
GYDataAccessLayer
is an entry point. This class sets and changes the data source.
Example:
GYDataAccessLayer da = new GYDataAccessLayer();
da.GetInfo((result, error) =>
{
if (error != null) { return; } // handling exception
GYUser user = result;
});
public class GYDataAccessLayer
{
public void GetUserInfo(Action<GYUser, Exception> act, string id)
{
GYDataSource dataSource = new GYDataSource(new GYLocalData());
dataSource.GetUserInfo(act, id);
dataSource.SetDataSource(new GYWebData());
dataSource.GetUserInfo(act, id);
}
}
public class GYDataSource
{
IGYDataAccess _gyDataAccess;
public GYDataSource(IGYDataAccess gyDataAccess)
{
_gyDataAccess = gyDataAccess;
}
public void SetDataSource(IGYDataAccess gyDataAccess)
{
_gyDataAccess = gyDataAccess;
}
public void GetInfo(Action<GYUser, Exception> act, string uid)
{
_gyDataAccess.GetUserInfo(act, uid);
}
}
I have a two classes to work with Local and Web data source. GYWebData
gets data from web and calls update method in GYLocalData
.
public interface IGYDataAccess
{
void GetUserInfo(Action<GYUser, Exception> act, string id);
}
public class GYWebData : IGYDataAccess
{
public void GetUserInfo(Action<GYUser, Exception> act, string id)
{
GYUserAPI.GetInfo(id, (result, error) =>
{
if (error != null)
{
act.Invoke(null, error);
return;
}
act.Invoke(result.Result, null);
GYLocalData gyLocalData = new GYLocalData();
gyLocalData.UpdateUserInfo(result.Result);
});
}
}
public class GYLocalData : IGYDataAccess
{
private const string ConnectionString = @"isostore:/Cache.sdf";
CacheDataContext DataBase;
CacheDataContextProfiles DataBaseProfiles;
private void CheckDataBase()
{
using (DataBase = new CacheDataContext(ConnectionString))
{
if (!DataBase.DatabaseExists())
{
DataBase.CreateDatabase();
}
}
}
public void GetUserInfo(Action<GYUser, Exception> act, string id)
{
CheckDataBase();
using (DataBaseProfiles = new CacheDataContextProfiles(ConnectionString))
{
try
{
var user = DataBaseProfiles.GetInfo(id);
if (user != null)
{
act.Invoke(user, null);
}
}
catch (Exception ex)
{
act.Invoke(null, ex);
}
}
}
public void UpdateUserInfo(GYUser user)
{
CheckDataBase();
using (DataBaseProfiles = new CacheDataContextProfiles(ConnectionString))
{
DataBaseProfiles.UpdatePersonProfile(user);
}
}
}
With this architecture it is inconvenient to work and hard to support. You have to write a lot of code and be very attentive (eg do not forget to call the update data method in the DB). Are there good patterns for such problems? How can I improve this code?