2014-09-13 2 views
3

При использовании нового конструктора 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 возвращать макетный экземпляр всех объектов во время разработки?

ответ

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

У меня был очень похожий вопрос в выходные дни; Мне нужен быстрый и простой способ предотвратить вызов API из ViewDidLoad при просмотре контроллера представления в дизайнере.

Вот вам быстрый и легкий чек, который я создал для работы с ним. (Снято с 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>(); 
    } 
} 
+0

Я думаю, что ваш способ тоже работает, но я думаю, что @ метод chkn является предпочтительным. Они следовали тому же шаблону от более старых дизайнеров, таких как WinForms. Однако ваш, вероятно, проще. – jonathanpeppers

Смежные вопросы