Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
DataBaseContext erstellen oder Repository per DI injizieren?
Ahrimaan
myCSharp.de - Member



Dabei seit:
Beiträge: 363
Herkunft: Thorn

Themenstarter:

DataBaseContext erstellen oder Repository per DI injizieren?

beantworten | zitieren | melden

Hallo Community,
ich wollte gerne eure Meinung zu etwas hören :

Ich habe ein Interface ILogger (zum Loggen)

public interface ILogger:IDisposable
    {
        void Debug<T>(T source, string message) where T : class;
        void Info<T>(T source, string message) where T : class;
        void Warning<T>(T source, string message) where T : class;
        void Critical<T>(T source, string message) where T : class;
        void Critical<T>(T source, string message, Exception ex) where T : class;
        void Critical<T>(T source, Exception ex) where T : class;
        string ConfigString {get; set; }
    }
Ich habe dazu eine Implementierung DatabaseLogger.

public class DataBaseLogger:ILogger.ILogger
    {
        public void Debug<T>(T source, string message) where T : class
        {
            using (var db = new DataBaseContext(ConfigString))
            {
                db.Logs.Add(new LogEntity(message,source.ToString(), DateTime.Now, string.Empty, LogLevel.Debug.ToString()));
                db.SaveChanges();
            }
        }

        public void Info<T>(T source, string message) where T : class
        {
            using (var db = new DataBaseContext(ConfigString))
            {
                db.Logs.Add(new LogEntity(message, source.ToString(), DateTime.Now, string.Empty,
                                          LogLevel.Info.ToString()));
                db.SaveChanges();
            }
        }

ILogger ist generisch gehalten , Databaselogger implementiert dieses und loggt die Nachrichten in eine Datenbank.
Ist es nun sinnvoller :

A.) dem Databaselogger das Datenbankhandling selber machen zu lassen
B.) Dem Databaselogger noch ein Repository zu übergeben ?

Bei beiden habe ich das evtl. Problem , dass ich zB. dem ILogger Interface ein Objekt oder String übergeben muss, welches je nach Anwendungsart ein Connectionstring oder ein Datepfad ist.

Gerade wenn es um DI geht stehe ich da ja nun vor einem Problem oder ?

Wie würdet Ihr das lösen ?
Grüße
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 7561
Herkunft: Waidring

beantworten | zitieren | melden

Hallo Ahrimaan,

überlege dir einfach ob du es Testen kannst. Wenn ja ist es gut, wenn nein muss was geändert werden (-> DI und für den Test dann mocken).
Da du dir es selbst überlegen sollst - um den Aha-Effekt zu haben - schreib ich nicht die (erwünschte) Antwort auf die Frage.
Zitat
Bei beiden habe ich das evtl. Problem , dass ich zB. dem ILogger Interface ein Objekt oder String übergeben muss, welches je nach Anwendungsart ein Connectionstring oder ein Datepfad ist.
Das Problem lässt sich durch eine IConfiguration lösen und diese kann dann per DI übergeben werden.
Da die Properties.Settings-Klasse partial ist kann hier eine eigene Klasse erstellt werden welche das IConfiguration implementiert und somit ist


iocContainer.Register<IConfiguration, Properties.Default>();
möglich.


mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
Ahrimaan
myCSharp.de - Member



Dabei seit:
Beiträge: 363
Herkunft: Thorn

Themenstarter:

beantworten | zitieren | melden

Hi,

mit deiner Frage nach dem Test, hast du mir die Antwort quasi schon gegeben : Natürlich muss ich ein Repository übergeben , bei einem Context kann ich ja in der Klasse nichts mehr Mocken.

Damit erübrigt sich auch die Frage nach der Konfiguration, das Repository kann ja auch auf Dateiebene laufen.

Danke und Gruß
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Ahrimaan am .
private Nachricht | Beiträge des Benutzers
Ahrimaan
myCSharp.de - Member



Dabei seit:
Beiträge: 363
Herkunft: Thorn

Themenstarter:

beantworten | zitieren | melden

Hi gfoidl,

ich hoffe ich habe nun so gehandelkt wie du es dir gedacht hast :
Das Interface wurde um eine Repository Property erweitert

    public interface ILogger:IDisposable
    {
        void Debug<T>(T source, string message) where T : class;
        void Info<T>(T source, string message) where T : class;
        void Warning<T>(T source, string message) where T : class;
        void Critical<T>(T source, string message) where T : class;
        void Critical<T>(T source, string message, Exception ex) where T : class;
        void Critical<T>(T source, Exception ex) where T : class;
        IRepository.IRepository<LogEntity> Repository { set; get; } 
    } 
Ich habe ein neues Projekt erstellt mit der LogEntity

    public class LogEntity
    {
        public LogEntity(string message,string source,DateTime logDate,string extMessage,string logLevel)
        {
            Message = message;
            Source = Source;
            ExtMessage = extMessage;
            LogDate = logDate;
            LogLevel = logLevel;
        }
        [Key]
        public int ID { get; private set; }

        [StringLength(200)]
        public string Message { get; private set; }

        [Required(AllowEmptyStrings = true)]
        [StringLength(500)]
        public string ExtMessage { get; private set; }

        [StringLength(200)]
        public string Source { get; private set; }

        [StringLength(20)]
        public string LogLevel { get; private set; }

        public DateTime LogDate { get; private set; }
    }

Unschön ist jetzt nur, dass das Repository nur eine Property ist und nicht per Constructor eingegeben wird. Ich überlege, das ILogger Interface als Abstrakte Klasse auszuführen.

Grüße
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 7561
Herkunft: Waidring

beantworten | zitieren | melden

Hallo Ahrimaan,

das IRepository würde ich auch der ILogger-Schnittstelle komplett raushalten, denn Repositories werden i.d.R. mit Datenbankzugriff assoziiert und der Logger sollte nciht darauf beschränkt sein.

D.h. im DataBaseLogger übergibst du per DI das IRepository (das auch über eine Container aufgelöst werden kann).


mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
private Nachricht | Beiträge des Benutzers
Ahrimaan
myCSharp.de - Member



Dabei seit:
Beiträge: 363
Herkunft: Thorn

Themenstarter:

beantworten | zitieren | melden

Hi,

da ich bisher nur mit MEF in Berührung kam, ist meien Frage nun : Woher weiß der DI Container, dass gerade das die Inmplementierung von ILogger im Constructor ein Repository braucht ?
Ich glaube cih sollte mir mal mehr die Doku von DI Frameworks anschauen ...

Danke für deine Hilfe !

Grüße
private Nachricht | Beiträge des Benutzers
winSharp93
myCSharp.de - Experte

Avatar #avatar-2918.png


Dabei seit:
Beiträge: 6155
Herkunft: Stuttgart

beantworten | zitieren | melden

Hallo Ahrimaan,

für den speziellen Fall eines Loggers würde ich eher auf DI verzichten - wie soll man sonst Fehler / Probleme mit dem DI-Container loggen, wenn er für's Logging einwandfrei funktionieren muss?
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 10083

beantworten | zitieren | melden

Indem man einen std.logger an solchen stellen als default vorsieht.


public class SafeLoggingClass
{
  public ILogger logger{ {get{return _logger;}set{_logger=value;}ILogger _logger=new DefaultILogger();
}
private Nachricht | Beiträge des Benutzers