Laden...

DataBaseContext erstellen oder Repository per DI injizieren?

Erstellt von Ahrimaan vor 12 Jahren Letzter Beitrag vor 12 Jahren 2.031 Views
A
Ahrimaan Themenstarter:in
350 Beiträge seit 2010
vor 12 Jahren
DataBaseContext erstellen oder Repository per DI injizieren?

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

6.911 Beiträge seit 2009
vor 12 Jahren

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.

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!"

A
Ahrimaan Themenstarter:in
350 Beiträge seit 2010
vor 12 Jahren

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ß

A
Ahrimaan Themenstarter:in
350 Beiträge seit 2010
vor 12 Jahren

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

6.911 Beiträge seit 2009
vor 12 Jahren

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!"

A
Ahrimaan Themenstarter:in
350 Beiträge seit 2010
vor 12 Jahren

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

5.742 Beiträge seit 2007
vor 12 Jahren

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?

F
10.010 Beiträge seit 2004
vor 12 Jahren

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();
}