How to refactor this C# code

2019-07-17 10:49发布

问题:

I have these functions

    public async Task<List<Machine>> GetMachines()
    {
        await Initialize();
        await SyncMachines();
        return await machineTable.ToListAsync();
    }

    public async Task InsertMachines(List<Machine> machines)
    {
        await Initialize();
        await Task.WhenAll(machines.Select(m => machineTable.InsertAsync(m)));
        await SyncMachines();
    }

I am writing a parent class to put these functions in, such that the functions getMachines() and InsertMachines() become getObject and InsertObject where the List<Machine> can be a list of any objects, so they can return and accept any type of list

How do I declare functions like this?

回答1:

According to your description, I created my azure sync table class as follows, you could refer to it:

public class AzureCloudSyncTable<TModel> where TModel : class
{
    public static MobileServiceClient MobileService = new MobileServiceClient(
        "https://{your-mobile-app-name}.azurewebsites.net"
    );
    private IMobileServiceSyncTable<TModel> syncTable = MobileService.GetSyncTable<TModel>();

    #region Offline sync
    private async Task InitLocalStoreAsync()
    {
        if (!MobileService.SyncContext.IsInitialized)
        {
            var store = new MobileServiceSQLiteStore("localstore.db");
            store.DefineTable<TModel>();
            await MobileService.SyncContext.InitializeAsync(store);
        }
        await SyncAsync();
    }

    private async Task SyncAsync()
    {
        await PushAsync();
        await syncTable.PullAsync(typeof(TModel).Name, syncTable.CreateQuery());
    }

    private async Task PushAsync()
    {
        try
        {
            await MobileService.SyncContext.PushAsync();
        }
        catch (MobileServicePushFailedException ex)
        {
            if (ex.PushResult != null)
            {
                foreach (var error in ex.PushResult.Errors)
                {
                    await ResolveConflictAsync(error);
                }
            }
        }
    }

    private async Task ResolveConflictAsync(MobileServiceTableOperationError error)
    {
        //var serverItem = error.Result.ToObject<TModel>();
        //var localItem = error.Item.ToObject<TModel>();

        //// Note that you need to implement the public override Equals(TModel item)
        //// method in the Model for this to work
        //if (serverItem.Equals(localItem))
        //{
        //    // Items are the same, so ignore the conflict
        //    await error.CancelAndDiscardItemAsync();
        //    return;
        //}

        //// Client Always Wins
        //localItem.Version = serverItem.Version;
        //await error.UpdateOperationAsync(JObject.FromObject(localItem));

        // Server Always Wins
        //await error.CancelAndDiscardItemAsync();
    }
    #endregion

    #region public methods
    public async Task<List<TModel>> GetAll()
    {
        await InitLocalStoreAsync();
        await SyncAsync();
        return await syncTable.ToListAsync();
    }

    public async Task Insert(List<TModel> items)
    {
        await InitLocalStoreAsync();
        await Task.WhenAll(items.Select(item => syncTable.InsertAsync(item)));
        await PushAsync();
    } 
    #endregion
}

Additionally, for more details about Handling Conflict Resolution, you could refer to adrian hall's book here.