Laden...

Klassendesign eines Dienstes, der Mails abrufen und verteilen soll

Erstellt von DavidT vor 15 Jahren Letzter Beitrag vor 15 Jahren 2.029 Views
DavidT Themenstarter:in
998 Beiträge seit 2007
vor 15 Jahren
Klassendesign eines Dienstes, der Mails abrufen und verteilen soll

Hallo,

ich habe so als erstes Programmierprojekt mal einen Mailverteiler als Dienst entwickelt. Gestern vor dem TV habe ich mir dann mal überlegt, wie man soetwas richtig entwickeln würde.
Die damalige Aufgabenstellung war es, einen Dienst zu schreiben der periodisch mehrere Mailaccounts abfragt und die erhaltenen Mails dann an eine Verteilerliste für jeden Account verschickt (Accounts und Verteilerliste in einem SQL05).

Damals hatte ich eine KLasse Watchdog die den Server gepollt hat, eine GetMail welche die Mails abgeholt hat und eine SendMail welches die Mails gesendet hat. Früher hatte ich zwischen jeder Klasse eine zirkuläre Abhängigkeit weil ich noch nicht so den Plan von Events hatte, konnte in Folgeprojekten also niemals etwas aus dem Code verwenden (Da konnte ich es direkt neu schreiben).

Mein heutiger Ansatz (Grad schnell zusammengeklickt) ist im Anhang, sagt mal bitte dazu ob die rangehensweise so ok ist oder was man anders machen sollte.

Danke im Voraus.

Gruß David

R
494 Beiträge seit 2006
vor 15 Jahren

Also ich würde das etwas anderst machen.

  • Der Core hat ne Liste mit allen MailAccounts (da fehlt wohl auch noch einiges an Informationen).
  • Der Watchdog als getrennte Sache der alle x Zeiteinheiten den Core dazuveranlasst auf neue Mails zu prüfen.
  • Dann evtl. ne MailChecker klasse welche welche vom Core aufgerufen wird und nen Account nach neuen Mails prüft dann evtl
  • MailGetter und MailSender ja vielleicht nicht die Methoden aber vom Prinzip der 2 Dinge klingt das gut.
  • Events würde ich ohne das Event am Ende bezeichnen
  • es heißt "Address"
  • Vielleicht noch ne Unterscheidung ob IMAP oder POP3 Account
DavidT Themenstarter:in
998 Beiträge seit 2007
vor 15 Jahren
  1. Ist es aufgabe des Cores die Emails abzurufen? Es gibt ja die nette Methode mit "Klassenname macht Funktion" um zu prüfen ob eine Methode richtig platziert ist und "Core ruft Email ab" kommt meiner Ansicht nach nicht hin g
  2. DIe Mailchecker-Funktion ist ja genau der Watchdog, der überwacht die Email Accounts ob neue Mails vorhanden sind, wenn ja, löst er das NewMailEvent aus.
  3. Die Methoden son MailGetter und SendMail sind bewusst so gewählt, da die jeweiligen Methoden einen eigenen Thread starten, eigentlich wäre hier besser "Beginxxxx" gewesen.
  4. Ups g Tippfehler
  5. Damals war als Aufgabenstellung das es nur POP-Accounts sind...

Also wie du bereits gemerkt hast ist es nur eine Skizze, habe da gestern etwas drüber nachgedacht und es dann heute morgen in Klassendesigner fix zusammengeklickt.

Aber danke für dein Feedback.

Gruß David

2.187 Beiträge seit 2005
vor 15 Jahren

Hi DavidT,

Bei MailServer sind die On-Methoden öffentlich, die sollten natürlich protected sein.
MailAccount ist auch klar, aber warum kennt der MailServerCore den IWatchDog und nicht die MailAccount's. Es wäre doch sinnvoller, wenn der MaileServerCore die IWatchDog's zu den MailAccount's erstellt.

Ansonsten sieht alles gut aus.

Gruß
Juy Juka

DavidT Themenstarter:in
998 Beiträge seit 2007
vor 15 Jahren

Hallo,

richtig, über die sichtbarkeit habe ich mir keine Gedanken gemacht, aber natürlich hast du recht, danke.
Was die Mails angeht hast du ebenfalls recht, das macht wirklich keinen Sinn. Womit ich zur nächsten Frage kommen würde, wenn ich die Collection der Accounts (es war so gedacht das der Watchdog nacheinander alle accounts prüft ob neue mails vorhanden sind) an den Watchdog übergebe, mache ich das ja wahrscheinlich per Propertie oder Konstruktor-Argument. SOllte man direkt die MailAccounts übergeben oder eine generalisierte Klasse Account, davon die Mail-Accounts ableiten und dann im Inerface nur die Account Klasse referenzieren? Weil wenn ich es direkt über die Mailaccounts mache, könnte ich nicht ohne weiteres einen Watchdog dahinter stöpseln der beispielsweise Ordner nach neuen Dateien durchsucht (So ein Szenario könnte es ja mal geben) weil ich ja nur Mailaccounts übergeben könnte.

Danke auch für dein Feedback.

Gruß David

2.187 Beiträge seit 2005
vor 15 Jahren

Hi DavidT,

Ich hab noch mal über alles nach gedacht und das sinnvollste währe, alles für die Ansteuerung der Accounts in Klassen zu Kapseln. Den WatchDog nur innerhalb eine Accounts zu benutzen oder ihn eventuell sogar immer wieder zu implementieren, da es ja für jeden Account sehr unterschiedlich sein wird/könnte.

Gruß
Juy Juka

[EDIT]
Ach ja, der Code der Programm-Klasse


  public class Programm
  {
    IEnumerable<IAccount> _MonitoredAccounts;
    IEnumerable<IAccount> _RecivingAccounts;

    public IEnumerable<IAccount> MonitoredAccounts
    {
      get { return _MonitoredAccounts; }
      //set { _MonitoredAccounts = value; }
    }

    public IEnumerable<IAccount> RecivingAccounts
    {
      get { return _RecivingAccounts; }
      //set { _RecivingAccounts = value; }
    }

    public Programm(IEnumerable<IAccount> MonitoredAccounts, IEnumerable<IAccount> RecivingAccounts)
    {
      this._MonitoredAccounts = MonitoredAccounts??new IAccount[]{};
      this._RecivingAccounts = RecivingAccounts??new IAccount[]{};
      foreach (IAccount iaccount in this.MonitoredAccounts)
      {
        iaccount.NewMail += OnNewMail;
      }
    }

    protected virtual void OnNewMail(object sender, EventArgs e)
    {
      new System.Threading.Thread(
        new AnsyncronMailSender(this.RecivingAccounts, sender as IAccount).Do).Start();
    }

    private class AnsyncronMailSender
    {
      IEnumerable<IAccount> _Targets;
      IAccount _Source;

      public AnsyncronMailSender(IEnumerable<IAccount> target, IAccount source)
      {
        _Targets = target;
        _Source = source;
      }

      public void Do()
      {
        string s = _Source.GetMail();
        foreach (IAccount account in _Targets)
        {
          account.SendMail(s);
        }
      }
    }
  }

Ich hab Einfachheit-Halber so getan als wäre ein Mail einfach ein String und hab die Übergabeparamter für GetMail-Ignoriert.
[/EDIT]