Search code examples
androidxamarinfirebasemvvmcross

MVVMCross Platform specific class that has method which returns instance of same class


Background: I'm trying to integrate Firebase into my MVVMCross app using its platform specific SDK's. The basic part of my setup is working, namely I can use the basic Firebase features to retrieve info from a Firebase database from within my viewmodel. It uses an interface in my PCL that has platform specific implementations in the UI projects.

Problem: I would like to, however, implement a method in my interface (and its implementations) that can deal with the fact that the Java SDK of Firebase has a class called "Firebase" with methods that return the same type ("Firebase"), such as the "Child" method in the Java SDK:

Firebase firebase = new Firebase("URI");
Firebase firebasechild = firebase.Child("test"); // Of same type!
firebasechild.DoStuff();

I'm trying to get similar functionality in my viewmodel:

firebase = Mvx.Resolve<IFirebaseConnection> ();
firebase.FirebaseConnection ("URI");
IFirebaseConnection firebasechild = firebase.Child("test");
firebasechild.DoStuff();

The relevant part of my interface in my PCL is:

public interface IFirebaseConnection
{
    void FirebaseConnection (string URI);

    IFirebaseConnection Child(string child); // Probably wrong?

    void DoStuff();
}

My setup.cs in my Android UI project contains:

Mvx.RegisterType<IFirebaseConnection, FirebaseDroid>();

The platform specific implementation in Android is:

public class FirebaseDroid : IFirebaseConnection
{
    protected Firebase firebase;

    public void FirebaseConnection (string URI)
    {
        var mvxTopActivity = Mvx.Resolve<IMvxAndroidCurrentTopActivity>();
        Firebase.SetAndroidContext (mvxTopActivity.Activity);
        firebase = new Firebase (URI);
    }

    public IFirebaseConnection Child (string child)
    {
        return firebase.Child (child); // This is obviously wrong
    }

    public void DoStuff(){// do something}
}

The above is obviously wrong since firebase.Child() is of type "Firebase" and not "IFirebaseConnection", or probably more correctly "FirebaseDroid". Is there a way to deal with methods of the same type as the class it is in when implementing platform specific services?


Solution

  • You could introduce a new private constructor.

    public class FirebaseDroid : IFirebaseConnection
    {
        protected Firebase firebase;
    
        public FirebaseConnection() {}
    
        private FirebaseConnection (Firebase firebase)
        {
            SetFirebase(firebase);
        }
    
        public void FirebaseConnection (string URI)
        {
            SetFirebase(new Firebase (URI));
        }       
    
        private void SetFirebase(Firebase firebase)
        {
            var mvxTopActivity = Mvx.Resolve<IMvxAndroidCurrentTopActivity>();
            Firebase.SetAndroidContext (mvxTopActivity.Activity);
            this.firebase = firebase;
        }
    
        public IFirebaseConnection Child (string child)
        {
            return new FirebaseConnection(firebase.Child (child));
        }
    
        public void DoStuff(){// do something}
    }