Mark code that doesn't run during development
When using the new Xamarin.iOS designer, it will automatically create your controllers, views, etc. so that your C # code will execute and actually appear on the design surface (instead of waiting until execution).
So, if you have a controller, the constructor will be called and ViewDidLoad
.
So let's say I have a controller like this:
class MyController
{
readonly ISomeService service;
public MyController(IntPtr handle) : base(handle)
{
service = MyIoCContainer.Get<ISomeService>();
}
}
Obviously during development the IoC container will be completely empty and throw an exception.
Is there a way to solve this problem using the Xamarin.iOS designer? Maybe #if !DESIGN_TIME
or something like that? Or is there a way I could make my IoC container return a mock instance of all objects at design time?
It is currently recommended that you use this class to implement the IComponent interface. For more information see this document . So your MyController class might look something like this:
[Register ("MyController")]
class MyController : UIViewController, IComponent
{
#region IComponent implementation
public ISite Site { get; set; }
public event EventHandler Disposed;
#endregion
readonly ISomeService service;
public MyController(IntPtr handle) : base(handle)
{
}
public override void AwakeFromNib ()
{
if (Site == null || !Site.DesignMode)
service = MyIoCContainer.Get<ISomeService>();
}
}
Note that there will always be a null
. The preferred place to initialize from a storyboard is method AwakeFromNib
. I've updated the sample code to reflect this.
I had a very similar question over the weekend; I need a quick and easy way to prevent the API from being called from ViewDidLoad when viewing the view controller in the designer.
Here you can quickly and easily check what I have created for this. (Taken from fooobar.com/questions/2163782 / ... )
The Studio Storyboard designer does not raise AppDelegate events, so you can use that to create a validation.
AppDelegate.cs
public partial class AppDelegate: UIApplicationDelegate
{
public static bool IsInDesignerView = true;
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
IsInDesignerView = false;
return true;
}
}
ViewController
public class MyController: UIViewController
{
readonly ISomeService service;
public MyController(IntPtr handle) : base(handle)
{
service = AppDelegate.IsInDesignerView ?
new Moq<ISomeService>() :
MyIoCContainer.Get<ISomeService>();
}
}