1

I am making a Xamarin Forms Cross platform app. I have been trying to figure out how to go about getting my app to integrate with the Azure Backend the best way. I have ran into a problem. It has been drilled into my head to try to build programs as loosely coupled as possible. But then I have been told to create my Azure Services class as a singleton to stop multiple creations and mucking up the backend connection

Since I cant use Interfaces with a singleton to make my app loosely coupled. I have to pick. I think I should go with interfaces, for loose coupling. But I don't know much about Backend development. Will creating multiple instances of my AzureServices Database class mess stuff up?

Thanks for any help.

Here is an example of the format of my AzureServices

namespace CoffeeCups
{

public class AzureService
{

public MobileServiceClient Client { get; set; } = null;

 IMobileServiceSyncTable<CupOfCoffee> coffeeTable;

public static bool UseAuth { get; set; } = false;

        public async Task Initialize()
        {
            if (Client?.SyncContext?.IsInitialized ?? false)
                return;


            var appUrl = "https://chattestjbapp.azurewebsites.net";


            //Create our client

            Client = new MobileServiceClient(appUrl);


            //InitialzeDatabase for path
            var path = "syncstore.db";
            path = Path.Combine(MobileServiceClient.DefaultDatabasePath, path);

            //setup our local sqlite store and intialize our table
            var store = new MobileServiceSQLiteStore(path);

            //Define table
            store.DefineTable<CupOfCoffee>();


            //Initialize SyncContext
            await Client.SyncContext.InitializeAsync(store);

            //Get our sync table that will call out to azure
            coffeeTable = Client.GetSyncTable<CupOfCoffee>();


        }

        public async Task SyncCoffee()
        {
            try
            {
                if (!CrossConnectivity.Current.IsConnected)
                    return;

                await coffeeTable.PullAsync("allCoffee", coffeeTable.CreateQuery());

                await Client.SyncContext.PushAsync();
            }
            catch (Exception ex)
            {
                Debug.WriteLine("Unable to sync coffees, that is alright as we have offline capabilities: " + ex);
            }

        }

        public async Task<IEnumerable<CupOfCoffee>> GetCoffees()
        {
            //Initialize & Sync
            await Initialize();
            await SyncCoffee();

            return await coffeeTable.OrderBy(c => c.DateUtc).ToEnumerableAsync(); ;

        }

        public async Task<CupOfCoffee> AddCoffee(bool atHome, string location)
        {
            await Initialize();

            var coffee = new CupOfCoffee
            {
                DateUtc = DateTime.UtcNow,
                MadeAtHome = atHome,
                OS = Device.RuntimePlatform,
                Location = location ?? string.Empty
            };

            await coffeeTable.InsertAsync(coffee);

            await SyncCoffee();
            //return coffee
            return coffee;
        }



        public async Task<bool> LoginAsync()
        {

            await Initialize();

            var provider = MobileServiceAuthenticationProvider.Twitter;
            var uriScheme = "coffeecups";



            var user = await Client.LoginAsync(Forms.Context, provider, uriScheme);


            if (user == null)
            {
                Settings.AuthToken = string.Empty;
                Settings.UserId = string.Empty;
                Device.BeginInvokeOnMainThread(async () =>
                {
                    await App.Current.MainPage.DisplayAlert("Login Error", "Unable to login, please try again", "OK");
                });
                return false;
            }
            else
            {
                Settings.AuthToken = user.MobileServiceAuthenticationToken;
                Settings.UserId = user.UserId;
            }

            return true;
        }    
    }
}
mugx
  • 9,869
  • 3
  • 43
  • 55
  • An IoC container can and when applicable should be configured to manage your object lifetimes. Meaning you can tell it that resolving a particular class should be in a singleton fashion. Which IoC container are you using? – ethane Jan 14 '18 at 08:09
  • I did not know what an IoC container was until today. So I have been trying to get MVVM Light working so I can use SimpleIoc. But my project is targeting the Net framework 4.5 and MVVM light does not seem to be liking it, at least in my current project. The ViewModelLocator it creates give my project all sorts of problems. It cant find the using Microsoft.Practices.ServiceLocation namespace. I tried installed the EnterpriseLibrary, but that wont work. Even when I comment out the problem areas of ViewModel then I get an error in the App.xaml with the ResourceDictionary... Ugh what a headache!! – John Butler Jan 14 '18 at 19:57
  • The Prism MVVM framework by far one of easiest to use and most powerful in my opinion. It provides you with a choice of different containers, like Unity or AutoFac. It is has quite a large community as well; tons of support. You can check it out here: https://github.com/PrismLibrary/Prism – ethane Jan 15 '18 at 04:29

0 Answers0