1

I have an iOS app, developed with Xamarin.iOS, that is using Ninject 3.3.0 for IoC. I am able to bind interfaces and implementations without issue, but I get a PlatformNotSupportedException on resolving those bindings with IResolutionRoot.Get<T>(). I am launching to a simulator on a connected Macbook. I have created a test (blank) iOS app to demonstrate the issue. Here are the relevant lines:

[Register("AppDelegate")]
public class AppDelegate : UIApplicationDelegate
{
  ...

  public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
  {
     ...

     var kernel = new StandardKernel();
     kernel.Bind<IFoo>().To<Foo>();

     var test = kernel.Get<IFoo>(); //exception thrown here

     return true;
  }
}

Here's the top of the stack trace (can provide more):

" at System.Reflection.Emit.DynamicMethod..ctor (System.String name, System.Type returnType, System.…"

According to this site, the kernel creates these DynamicMethod's for its bindings. Since Ninject is supported by .Net Standard 2.0, why am I getting this exception from such a simple operation?

Joseph
  • 903
  • 1
  • 10
  • 25
  • Did you try using https://www.nuget.org/packages/Portable.Ninject/? I've been using that in my PCL and iOS/Android project and didn't have any problems. – zhuber Feb 16 '18 at 09:57
  • Yeah, that's the one Rob is using in his article. His sample code actually includes both Ninject and Portable.Ninject libraries, but it doesn't appear to reference the former at all. – Joseph Feb 19 '18 at 15:18

1 Answers1

7

Update: Portable.Ninject works, so use that instead if you're on iOS. The following is an explanation of how I got there and why regular Ninject doesn't work.

System.Reflection.Emit is not supported. Which likely means much of Ninject will not work for iOS.

These links were particularly misleading to me:

https://developer.xamarin.com/api/type/System.Reflection.Emit.DynamicMethod/

Having now read about this limitation, it's obvious the generation mentioned in this article impedes Ninject from working, though it's not explicitly stated.

http://arteksoftware.com/ioc-containers-with-xamarin/

The writer of this article mentions the limitation, though it appears he got it working.

Joseph
  • 903
  • 1
  • 10
  • 25
  • 2
    tl;dr: use Portable.Ninject – Lee Richardson Feb 21 '18 at 04:20
  • 2
    Agreed. I've updated my answer to make the solution more accessible. – Joseph Feb 21 '18 at 14:51
  • You can't use Portable.Ninject with .net standard libraries so this is not a solution to the problem – Stefanija Apr 18 '19 at 12:07
  • @Merian It is, because this question pertains to Xamarin.iOS. In the question I linked to an answer that indicated .NET Standard support, so theoretically you should be able to use Portable for .NET Standard as long as iOS isn't one of your target platforms – Joseph Apr 18 '19 at 19:27
  • You mean: You should be able to use Portable as long as iOS is one of your targets with a big warning the package may not be fully compatible with your project on the class library projects. And according to the last sentence in the question .Net Standard looks like it is used :). – Stefanija Apr 19 '19 at 08:20
  • @Merian I wanted to use it (hence the question), but to fix the exception I had to use Portable for iOS (hence the answer). So my other platforms use Ninject, but iOS uses Portable. I had to restructure things to get to that fix, but it does solve the problem. It sounds like your projects are structured differently. Hope this helps – Joseph Apr 19 '19 at 13:38