使用新的Xamarin.iOS设计器时,它会自动创建您的控制器,视图等,以便您的C#代码在设计图面上运行并实际呈现(而不必等到运行时)。
因此,如果你有一个控制器,它的构造函数和ViewDidLoad
将被调用。
所以我想说我有一个像这样的控制器:
class MyController
{
readonly ISomeService service;
public MyController(IntPtr handle) : base(handle)
{
service = MyIoCContainer.Get<ISomeService>();
}
}
显然在设计时,IoC容器将完全为空并抛出异常。
有没有办法用Xamarin.iOS设计师解决这个问题?也许是#if !DESIGN_TIME
或那种性质的东西?或者有没有办法让我的IoC容器在设计时返回所有对象的模拟实例?
答案 0 :(得分:2)
目前推荐的方法是让您的类实现IComponent接口。有关详细信息,请参阅this doc。所以你的MyController类看起来像这样:
[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>();
}
}
请注意,网站在构造函数中始终为null
。从故事板初始化的首选位置是AwakeFromNib
方法。我更新了代码示例以反映这一点。
答案 1 :(得分:1)
周末我有一个非常相似的问题;我想要一种快速简便的方法来阻止在查看设计器中的视图控制器时从ViewDidLoad进行API调用。
这是我为处理它而创建的快速简单的检查。 (摘自https://stackoverflow.com/a/25835680/841832)
Studio Storyboard设计器不会调用AppDelegate事件,因此您可以利用它来创建支票。
<强> 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>();
}
}