从在Windows服务和ASP.NET一个DLL记录 [英] Logging from a DLL in both Windows service and ASP.NET

查看:149
本文介绍了从在Windows服务和ASP.NET一个DLL记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创建了这是从一个Windows服务,Windows Forms和ASP.NET组件引用一个.NET的DLL。包含在DLL是相当多的日志记录到文本日志文件。这是直截了当足够的服务和WinForms,但显然不是简单的尝试写入通过ASP.NET中的日志文件。

I've created a .NET DLL which is referenced from a Windows service, windows forms and ASP.NET assemblies. Included in the DLL is quite a bit of logging to a text log file. This is straight forward enough from the service and winforms, but obviously not as straight forward trying to write to a log file through ASP.NET.

任何人都可以提供关于如何去这样一些建议吗?我想保持记录code的DLL,Windows服务和ASP.NET应用程序之间共享,因此

Can anyone provide some tips on how to go about this? I want to keep the logging code in the DLL, hence shared between the Windows service and the ASP.NET app.

推荐答案

这听起来像一个坏主意。每当你尝试创建暗箱式code,它神奇地适用于所有情况,它总是会导致无法控制的意大利面条code,从长远来看。举例来说,如果有一天你决定,你需要两个窗口服务,这两个使用相同的通用DLL,但其中一人需要登录到Windows事件日志和其他需要登录到一个文本文件中。现在,这是不是你的DLL那么容易自动确定应如何记录和code变得更加混乱和复杂。

That sounds like a bad idea. Whenever you try to create black-box type code that just magically works in all situations, it always leads to unmanageable spaghetti code in the long run. For instance, what if one day you decide that you need two windows services that both use this same common DLL, but one of them needs to log to the windows event log and the other needs to log to a text file. Now, it's not as easy for your DLL to automatically determine how it should log, and the code gets more messy and complicated.

依赖注入(DI)来解决这些问题非常优雅。日志是一个单独的活动,所以它应该由一个独立的记录器类来处理。如果日志记录在自己的类处理,则成为使用它的其他类的依赖。和类不应该隐瞒自己的依赖关系,而是应该要求他们进行注入到他们。有工具和框架做DI,而只是要求你的依赖在构造函数只是罚款了。

Dependency Injection (DI) solves these problems very elegantly. Logging is a separate activity, so it ought to be handled by a separate logger class. And if logging is handled in its own class, then it becomes a dependency of the other classes that use it. And classes should not hide their dependencies, but should require them to be "injected" into them. There are tools and frameworks for doing DI, but simply requesting your dependencies in your constructor is just fine too.

要做到这一点的DI方式,你首先需要创建一个接口为您的记录,例如:

To do it the DI way, you first would need to create an interface for your logger, for instance:

Public Interface ILogger
    Sub WriteEntry(message As String)
End Interface

然后,在每个需要进行日志类,你会要求在构造函数中的记录,例如:

Then, in each class that needs to perform logging, you would ask for the logger in the constructor, for instance:

Public Class MyBusiness
    Public Sub New(logger As ILogger)
        _logger = logger
    End Sub

    Private _logger As ILogger

    Public Sub DoWork()
        _logger.WriteEntry("Doing work")
    End Sub
End Class

正如你所看到的,现在你已经完全从业务类中删除记录的内部工作原理的任何知识,所以在实现该接口的任何类,可以给它,它仍然工作。这样做就好像这是很释放。现在,您可以再使用该业务类的任何类型的项目,无论是用于记录这些应用程序可能有什么样的要求。你可以给它一个记录写入到一个文本文件,和事件日志,数据库,屏幕和电子邮件,你的名字 - 一切无需接触使用它的企业级

As you can see, now you have completely removed any knowledge of the inner workings of logging from your business class, so any class that implements that interface could be given to it and it would still work. Doing it like this is very freeing. Now you can reuse that business class in any type of project, no matter what requirements for logging those applications may have. You might give it a logger that writes to a text file, and event log, a database, the screen, and email, you name it--all without ever touching your business class that uses it.

现在,您可以轻松地创建两个单独的 ILogger 接口的实现,一个是服务,一个用于ASP.NET网站:

Now, you can easily create two separate implementations of the ILogger interface, one for services and one for ASP.NET sites:

Public Class MyAspLogger
    Implements ILogger

    Public Sub WriteEntry(message As String) Implements ILogger.WriteEntry
        ' Do whatever an ASP project must do to log
    End Sub
End Class 

Public Class MyServiceLogger
    Implements ILogger

    Public Sub WriteEntry(message As String) Implements ILogger.WriteEntry
        ' Do whatever a service project must do to log
    End Sub
End Class

然后从你的ASP项目,您可以创建这样的业务对象:

Then from your ASP project, you could create the business object like this:

Dim business As New MyBusiness(New MyAspLogger())

和从服务项目中,你可以像这样创造的:

And from your service project, you could create it like this:

Dim business As New MyBusiness(New MyServiceLogger())

在理想情况下,你会创建一个为你创建你的业务对象工厂类,所以您不必手动创建一个记录器(和你的其他所有依赖关系)每次你需要创建时间 MyBusiness 对象。

有一个工厂没有具体的实施要求,它只是一个统称归类班。一个工厂类也只是任何一类,其唯一/主要目的是实例与其他类的对象。在一个理想的世界,用DI,你永远不使用的关键字在你的code的任何地方,除了在工厂类,但是这并不总是可行的。一旦你开始宣布所有你的依赖,你会发现,它需要的code多行,因为你必须先创建所有的依赖实例化一个对象。例如:

There's no specific implementation requirements for a factory, it's simply a general term to categorize classes. A factory class would just be any class whose sole/main purpose is to instantiate objects from other classes. In an ideal world, with DI, you'd never use the New keyword anywhere in your code, except in factory classes, but that's not always practical. Once you start declaring all your dependencies, you'll find that it takes many lines of code to instantiate a single object because you have to first create all the dependencies. For instance:

Dim fileWriter As IFileWriter = New MyFileWriter()
Dim logger As ILogger = New MyServiceLogger(fileWriter)
Dim dataAccess As IDataAccess = New MyDataAccess()
dim business As IBusiness = New MyBusiness(logger, dataAccess)
' Ta da!! I finally have a business object that I can now use

所以,如果你需要在同一个项目中创建多个地方 MyBusiness 的对象,这是一个很大的复制code。如果没有其他原因不是为了方便,是有意义的有一个工厂,所以你可以这样做:

So, if you need to create MyBusiness objects in multiple places in the same project, that's a lot of copied code. If for no other reason than for convenience, it makes sense to have a factory, so you can just do this:

Dim factory As IBusinessFactory = New MyBusinessFactory()
Dim business As IBusiness = factory.NewMyBusiness()

然而,还有许多其他充分的理由使工厂类。您可能需要创建多个记录器,例如,点播,里面 MyBusiness ,所以在这种情况下, MyBusiness couldn T简单地问了一个 ILogger 在其构造,但也可以,而是要求一个 ILoggerFactory 该实施一个 NewLogger 方法。然后,你可以有两个独立的记录器工厂:一个是返回要求新的 MyAspLogger 对象,以及一个用于创建新的 MyServiceLogger 对象来代替。因此,在这种方式,一个工厂可以,本身成为其他类的依赖关系。

However, there are many other good reasons for making factory classes. You may need to create multiple loggers, for instance, on demand, inside MyBusiness, so in that case, MyBusiness couldn't simply ask for a single ILogger in its constructor, but it could, instead, ask for an ILoggerFactory which implemented a NewLogger method. Then you could have two separate logger factories: one that returns new MyAspLogger objects upon request, and one that creates new MyServiceLogger objects instead. So in that way, a factory can, itself, become a dependency of other classes.

另一个很好的理由为工厂是因为你会发现,code实例化的所有对象和电线他们一起在不同的配置,在其本身,一种特定的业务逻辑它不愧为模块化的方式分离出来。

Another good reason for factories is because you'll find that the code that instantiates all the objects and wires them all together in different configurations is, in and of itself, a specific kind of business logic which deserves to be separated out in a modular way.

这篇关于从在Windows服务和ASP.NET一个DLL记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆