C# - Pass dynamic string as a Class Type

Gayatri Gokhale 1 Reputation point
2021-02-23T04:49:06.53+00:00

In Xamarin.Forms app, I am calling a service to sync my all table data using web api. For that I have Table like this.

[Table("AllTableSyncData")]
public class AllTableSyncData
{
    [AutoIncrement,PrimaryKey]
    public int Id { get; set; }
    public int TableId { get; set; }
    public string TableName { get; set; }
    public string ApiClassName {get; set; }
}

Every time user is offline my data will be saved in this table and when user comes back online, this data will be synced with my remote databse.

For that I have written service. In this particular table, as user may enter data into various tables, I have only stored Id and tablename of that table, and the time of sync, I will fetch record for that Id and will send to api. my service looks like this.

 public class Service1 : Service
    {
        public Service1()
        {
        }

        public override IBinder OnBind(Intent intent)
        {
            return null;
        }

        public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
        {
            return OnStartCommandAsync(intent, flags, startId).Result;
        }

        public async Task<StartCommandResult> OnStartCommandAsync(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
        {            
            try
            {
                // base.OnStartCommand(intent, flags, startId);
                var list = JsonConvert.DeserializeObject<List<AllTableSyncData>>(intent.GetStringExtra("SyncList"));

                var current = Connectivity.NetworkAccess;

                if (current == NetworkAccess.Internet)
                {               
                    foreach (var obj in list)
                    {
                        Uri uri = new Uri($"{Constants.URL}/{obj.ApiClassName}");

                        //if(obj.TableName == “Table1”)

                        await AddDataToRemote(obj, obj.TableId,obj.TableName).ConfigureAwait(false);                              
                    }                    
                }
            }
            catch (Exception ex)
            {
            }
            return StartCommandResult.Sticky;
        }

        public static T GetValue<T>(string value)
        {
            return (T)Convert.ChangeType(value, typeof(T));
        }

        //private async Task AddDataToRemote<T>(Uri uri1,AllTableSyncData obj,T item)
        private async Task AddDataToRemote<T>(T obj1, int id,string name)
        {
            try
            {

                Uri uri = new Uri($"{Constants.URL}/Table1");
                using (var connection = new SQLiteConnection(Constants.DatabasePath))
                {
                    string objectJson = string.Empty;

                    // I have to check like this for my remaining 15 tables
                    //if (obj.TableName == “Table1”)
                    //{
                    //    List<Table1> queryresult = new List<Table1>();
                    //    queryresult = connection.Query<Table1>("SELECT * FROM " + obj.TableName + " Where Id=" + obj.TableId);
                    //    if (queryresult != null && queryresult.Count > 0)
                    //    {
                    //        objectJson = JsonConvert.SerializeObject(queryresult);
                    //    }
                    //}

                   // So I want to use something like this
                    var type = GetValue<T>(name);
                    var queryresult = connection.Query<type>("SELECT * FROM " + name + " Where Id=" + id);

                    if (queryresult != null && queryresult.Count > 0)
                    {
                        objectJson = JsonConvert.SerializeObject(queryresult);
                    }
                    using (var client = new HttpClient())
                    {
                        StringContent content = new StringContent(objectJson, Encoding.UTF8, "application/json");

                        HttpResponseMessage response = null;

                        try
                        {
                            response = await client.PostAsync(uri, content);

                            if (response.IsSuccessStatusCode)
                            {
                                var readTask = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                                var json1 = JsonConvert.DeserializeObject(readTask);
                                //if (obj.TableName == "Table1")
                                //{
                                    var queryresult1 = connection.Query<T>("UPDATE " + name + " set WebId=" + Convert.ToInt32(json1)+" WHERE Id="+id);
                                //}                                    
                            }
                        }
                        catch (Exception ex)
                        {
                        }
                    }                    
                }
            }
            catch (Exception ex)
            {
            }
        }

        public override void OnDestroy()
        {
            StopSelf();
            base.OnDestroy();
        }

    }

As list will have entry of various table names, I want to do some generic code so that I will not have to check for table name and then fetch record from that table. For that I also tried Generic Method of type T but somewhere I am doing it wrong.

Can you please help me ?

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,366 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,117 questions
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.