2014-10-15 2 views
1

У меня есть три проекта в моем решенииИсключая циклическую зависимость и создать объект

  • ClassLibrary => Ссылки InterfaceLibrary, UIProject содержит (CountDownTimer.cs)

  • InterfaceLibrary содержит (ICountDownTimer.cs)

  • UIProject => Ссылки InterfaceLibrary содержит (frmMain.cs, Controller.cs)

Я читал, что добавление интерфейсов - способ устранения круговой зависимости, я попытался найти ответ на свою проблему, но продолжаю отставать.

Мне нужно создать новый объект CountDownTimer в классе контроллера, может кто-нибудь, пожалуйста, сообщите или помочь

public partial class frmMain : Form 
{ 
    //Reference to the Controller class, so we can call it 
    private Controller MController { get; set; } 

    //Constructor 
    public frmMain(Controller cntr) 
    { 
     MController = cntr; 
     InitializeComponent(); 
    } 

    private void frmMain_FormClosed(object sender, FormClosedEventArgs e) 
    { 
     //Because controller is the main class, closing the form won't exit the program 
     //So we need to close it with an exit call 
     Application.Exit(); 
    } 

    private void btn_Start_Click(object sender, EventArgs e) 
    { 
     MController.StartTimer(); 
    } 
} 


public class Controller : ApplicationContext 
{ 
    //Store a reference to the UI 
    internal frmMain MainUI { get; set;} 
    private ICountDownTimer timer; 

    public Controller() 
    { 

     MainUI = new frmMain(this); 
     MainUI.Show(); 
    } 

    internal void StartTimer() 
    { 

    } 
} 

public class CountDownTimer : ICountDownTimer 
    { 
     private int seconds; // Time in seconds 
     private int reSetValue; // Time in seconds 
     private System.Windows.Forms.Timer timer1; 
     private Controller parent; 

     public CountDownTimer(Controller parent, int seconds) 
     { 
      this.parent = parent; 
      this.seconds = seconds; 
      reSetValue = seconds; 

      timer1 = new System.Windows.Forms.Timer(); 
      timer1.Tick += new EventHandler(timer1_Tick); // Add Handler(timer1_Tick) 
      timer1.Interval = 1000; // 1 second 

      //parent.TickUpdate(("" + seconds/60).PadLeft(2, '0') + "m:" + ("" + seconds % 60).PadLeft(2, '0') + "s"); 
     } 

     private void timer1_Tick(object sender, EventArgs e) 
     { 
      seconds--; // Decrement seconds 
      if (seconds == 0) // Stop Timer at 0 
      { 
       timer1.Stop(); // Stop timer 
      } 
      else 
      { 
       //parent.TickUpdate(convertSecondToMMSS()); 

       if (seconds % 60 == 0 || seconds >= 1 && seconds <= 10) 
       { 
        //parent.TickUpdate(seconds); 
       } 
      } 
     } 

     void ICountDownTimer.StartTimer() 
     { 
      timer1.Start(); // Start Timer 
     } 

     public string convertSecondToMMSS() 
     { 
      TimeSpan t = TimeSpan.FromSeconds(seconds); 
      string str = string.Format("{0:D2}m:{1:D2}s", 
       t.Minutes, 
       t.Seconds); 

      return str; 
     } 

     void ICountDownTimer.StopTimer() 
     { 
      timer1.Stop(); 
     } 

     void ICountDownTimer.ResetTimer() 
     { 
      timer1.Stop(); 
      seconds = reSetValue; 
      //parent.TickUpdate(convertSecondToMMSS()); 
     } 

     void ICountDownTimer.SetTimer(int seconds) 
     { 
      timer1.Stop(); 
      this.seconds = seconds; 
      reSetValue = seconds; 
      //parent.TickUpdate(convertSecondToMMSS()); 
     } 
    } 

public interface ICountDownTimer 
{ 
    void StartTimer(); 

    void StopTimer(); 

    void ResetTimer(); 

    void SetTimer(int seconds); 
} 
+0

Я мог бы быть в меньшинстве здесь, но у меня никогда не было причин помещать интерфейсы в отдельный проект из их реализации, если в некоторых особых случаях не добавлены _additional_-реализации. –

ответ

3

CountdownTimer не должно быть никакой не знает о контроллере.

Контроллер должен создавать экземпляр и ссылаться на CountdownTimer и использовать его методы и выдавать соответственно, например. он должен подписаться на обработчик событий Timers Tick для обновления пользовательского интерфейса на правильной частоте.

Взгляните на Hollywood Principle, в котором используется инструкция «Не звоните нам, мы вам позвоним». Применение этого режима к вашему сценарию означает, что CountdownTimer не должен «вызывать» контроллер, контроллер должен «вызывать» CountdownTimer. В этой записи в Википедии приведена следующая выдержка:

Ключом, позволяющим это сделать, является жертвовать элементом управления. Вместо вашей программы, запускающей систему, система запускает вашу программу . В нашем примере наша программа могла регистрироваться для событий таймера, и писать соответствующий обработчик событий, который обновляет координаты. Программа будет включать в себя другие обратные вызовы для ответа на другие события, , например, когда система требует, чтобы часть окна была перерисована. Система должна обеспечивать соответствующую контекстную информацию, чтобы обработчик мог выполнить задачу и вернуть ее. Программа пользователя больше не включает явный путь управления , кроме инициализации и регистрации.

Единственное, что касается UIProject, - это управление пользовательским интерфейсом. Следовательно, он не должен содержать реализацию того, что может быть общим классом CountdownTimer.

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