MonoTouch/MonoDroid and Dependency Injection

RossDargan.0957RossDargan.0957 GBInsider, University ✭✭

Is there any technical reason why the xamarin couldn't implement dependency injection into the framework, especially when it comes to activity/viewmodel selection. I.e in android:-

Intent intent = new Intent(this, typeof(SyncStartActivity));

If SyncStartActivity didn't have a default constructor a service locator would be used, and in iOS when a segue or what ever else is used again a service locator could be used.

This would be massively helpful!

Posts

  • NicWiseNicWise NZMember, Insider, Beta mod

    Have a poke around MvvmCross (https://github.com/slodge/MvvmCross) I think @slodge uses DI in there.

    But I dont think Xamarin should bake it in. Not everyone wants to use DI (I dont, for example)

  • JonathanPryorJonathanPryor USXamarin Team Xamurai

    Is there any technical reason why the xamarin couldn't implement dependency injection into the framework,

    Not necessarily...

    especially when it comes to activity/viewmodel selection...If SyncStartActivity didn't have a default constructor a service locator would be used

    That can't work at all. Android requires that Activities (and Services, and...) have a default constructor. If there is no default constructor, Android bails, an exception is thrown, and everyone is unhappy.

    Now, you certainly could provide a default constructor which invokes another constructor while using some IoC container to grab the other constructor arguments, but no IoC container can get rid of Android's requirement that your type have a default constructor.

    Further note that the entire StartActivity()/etc. infrastructure is there to reduce barriers between processes. The Intent that you're starting need not be a type you control, nor need it even be in your process (even if it is a type you control!).

    So I'm not at all sure what an IoC container could do for Activities/etc.

  • MartinWestwood.8875MartinWestwood.8875 USUniversity

    We have had a lot of success using TinyIOC for dependency injection.

  • StuartLodgeStuartLodge USBeta ✭✭✭

    +1 for what @JonP says:

    especially when it comes to activity/viewmodel selection...
    If SyncStartActivity didn't have a default constructor a service locator would be used

    >

    That can't work at all. Android requires that Activities (and Services, and...) have a default constructor. If there is no default constructor, Android bails, an exception is thrown, and everyone is unhappy.

    In Mvx we get around this by using an OnCreate handler to do our ViewModel-based IoC

    Even if you don't want to use Mvx, you should still be able to use the same sort of technique - just do your ServiceResolution in OnCreate (but watch out for oddities in fragment lifecycle and in the lifecycle of orientation-enabled Activities)

  • SunderSunder USMember

    @MartinWestwood Since you have a lot of success using TinyIoC, i have a quick question.

    Where is the proper place to do my registration in an Android app? It seems that in the OnCreate function is not correct.

    I've noticed that if I launch the android app in the debugger, do some testing, and then stop running via the stop button in Xamarin Studio, the app will be "tombstoned", or running in the background.

    The next time I run it, the registration that I have added to the OnCreate function of my main activity, is not called and then future calls to TinyIoC's resolve function will fail, throwing an exception. If I kill the app from settings and re-launch, everything is fine.

  • JonathanPryorJonathanPryor USXamarin Team Xamurai

    Application-wide initialization should not be done from Activity.OnCreate(), as any Activity can be launched at any time programmatically.

    You should instead consider subclassing Application for app-global work:

    [Application]
    public class MainApp : Android.App.Application
    {
        public MainApp(IntPtr handle, JniHandleOwnership transfer)
            : base(javaReference, transfer)
        {
        }
    
        public override void OnCreate()
        {
            base.OnCreate();
            //app init ...
        }
    }
    
  • SunderSunder USMember

    @jonp thanks for the quick reply! I will give that a try.

Sign In or Register to comment.