如何正确访问自己的Logger类

时间:2015-01-06 13:42:09

标签: vb.net

我在类库项目中有自己的简单记录器类,它在许多其他项目中使用属于我的解决方案。现在我以这种方式在顶级消费它的每个类中使用它:

Private Logger As New Logger("C:\someLogFile.log")

然后在我使用它的代码中:

Logger.LogIt("Start part extracting files...")

我总是需要在每个类中创建它的实例及其无聊有时...我知道我可以创建静态Logger类并克服问题但是它是正确的方式还是我正在做的方式是否可以根据OOP?你觉得怎么样?

编辑:您如何看待使用界面的解决方案我刚刚实现了您的想法?

围绕一个解决方案在许多其他项目中使用的第一个项目(Logger项目):

Imports System.IO

    Public NotInheritable Class Logger
#Region "Fields"
        Private Shared ReadOnly _locker As New Object()
#End Region
#Region "Constructors"
    Public Sub New()
    End Sub
#End Region
#Region "Log function"
    Public Sub LogIt(ByVal msg As String, ByVal logMessage As String, Optional Path As String = "", Optional ByVal IsDebug As Boolean = False)
        If File.Exists(Path) Then
            If IsDebug Then
                Debug.Print(DateTime.Now & "> | " & msg & " | " & logMessage)
            Else
                Using w As TextWriter = File.AppendText(Path)
                    w.WriteLine(DateTime.Now & "> | " & msg & " | " & logMessage)
                    w.Flush()
                End Using
            End If
        Else
            If IsDebug Then
                Debug.Print(DateTime.Now & "> | " & msg & " | " & logMessage)
            Else
                SyncLock _locker
                    Using w As TextWriter = File.CreateText(Path)
                        w.WriteLine(DateTime.Now & "> | " & msg & " | " & logMessage)
                        w.Flush()
                    End Using
                End SyncLock
            End If
        End If
    End Sub



#End Region

我在此项目中添加了额外的ILog.vb接口:

Public Interface ILog

    Property LoggerPath As String
    Sub LogIt(ByVal msg As String, ByVal logMessage As String, ByVal Path As String, Optional ByVal IsDebug As Boolean = False)

End Interface

现在有一个类将使用Logger,例如下面这个。 (LoggerPath将从beggining上的xml序列化来到MainProcessRunner的构造函数),例如C:/file.txt:

Public Class MainProcessRunner
    Implements ILog

    Private Property LoggerPath As String Implements ILog.LoggerPath
    Private CollectionList As New List(Of ImportRunner)

    Public Sub New(ByVal LoggerPath As String)

        Me.LoggerPath = LoggerPath
CollectionList.Add(New ImportRunner(GPCollectTimePeriod.EveryMidnight, KpiName.Availability, MobileGenerationName.GSM, Me))

 For Each item In CollectionList
            If TypeOf item Is ICollectPeriod Then
                Dim runDaily As ICollectPeriod = TryCast(item, ICollectPeriod)
                runDaily.RunDaily()
            End If
        Next

...

   Public Sub LogIt(msg As String, logMessage As String, Path As String, Optional IsDebug As Boolean = False) Implements ILog.LogIt
        Dim Logger As New Logger
        Logger.LogIt(Alert.Write(MsgType.INFO), logMessage, Me.LoggerPath, True)
    End Sub

End class

正如你在内部构造函数中看到的那样,我通过以下方式调用其他类:

 runDaily.RunDaily()

然后在类ILog接口下面传递,因此我将从MainProcessRunner获得日志路径,然后我只需要填充msgtype和消息字符串:

Imports ImportJob

Public Class ImportRunner
    Implements ICollectPeriod

    Private Log As ILog
        Private BeginImport As New ImportStart
        Private GPCollectTimePeriodInMinutes As GPCollectTimePeriod
        Private KpiName As KpiName
        Private MobileGeneration As MobileGenerationName

        Public Sub New(ByVal GPCollectTimePeriodInMinutes As GPCollectTimePeriod, ByVal KpiName As KpiName, ByVal MobileGenerationName As MobileGenerationName, ByVal log As ILog)
            Me.GPCollectTimePeriodInMinutes = GPCollectTimePeriodInMinutes
            Me.KpiName = KpiName
            Me.MobileGeneration = MobileGenerationName
            Me.Log = log
        End Sub

        Public Sub RunDaily() Implements ICollectPeriod.RunDaily

            Log.LogIt(Alert.Write(MsgType.INFO), "sdsd", Log.LoggerPath, True)

    ....

        End Class

在这一行中,Log.LoggerPath被称为(C:/file.txt:)

 Log.LogIt(Alert.Write(MsgType.INFO), "sdsd", Log.LoggerPath, True)

从类ImpotStart,如果需要,我可以将Log作为ILog进一步传递给下一个类构造函数,如果该类将实现ILog接口。等等.. 您如何看待该解决方案?

4 个答案:

答案 0 :(得分:1)

您需要的是一个设计模式"Singleton",它确保只能创建该类的单个实例(单例):

using System;

namespace Singleton.Structural
{

  class Singleton
  {
    private static Singleton _instance;


    // Constructor is 'protected'
    protected Singleton()
    {

    }


    public static Singleton Instance()
    {

      // Uses lazy initialization.
      // Note: this is not thread safe.

      if (_instance == null)
      {
        _instance = new Singleton();
      }


      return _instance;
    }
  }
}

答案 1 :(得分:1)

OOP方式是执行依赖注入,以将Logger类的同一实例发送到需要它的每个类中。

然而,让你的班级静态绝对没有错。

答案 2 :(得分:0)

你只做正确的事。如果你厌倦了调用object.Method name。

使用Common Method将此(即对象方法)放在项目的基类中,并在每个页面中调用该方法。



Public void LogError(string error)
{
Logger.LogIt(error);
}




您可以通过catch语句中的LogError调用它。

最好阅读以下链接,了解项目的更好的记录方法

http://www.asp.net/web-forms/overview/getting-started/getting-started-with-aspnet-45-web-forms/aspnet-error-handling

答案 3 :(得分:0)

我读到如果在解决方案中的几乎每个区域都使用了某个对象,则可以使用static / share,因此logger足以将其用作静态/共享,并且仅对消息文本进行更改,并通过其构造函数进行路径传递。 / p>

我不认为单身人士在这种情况下可能会很好,因为他需要跟踪他对每个班级的引用,如果他有20个项目在一个解决方案中有多个班级,那将会非常复杂,所以我认为它更好使Logger静止。

或者只是保持你现在正在做的事情,因为每个类都有自己的Logger实例。只有当你有大量的数据流时,问题才在于文件路径。