最近事情比较多,有预研的,有目前正在研发的,都是很需要时间的工作,所以导致这周只写了两篇Orchard系列的文章,这边不能保证后期会很频繁的更新该系列,但我会写完这整个系列,包括后面会把正在研发的东西跟大家一起分享(架构、思想上的分享)。

今天我们来看一看Orchard中的Logging Component。

日志在Orchard中的使用

像这样的代码大家在Orchard中肯定经常见到,那么NullLogger.Instance是什么?大量使用依赖注入的Orchard会把真正的日志记录器放在一个静态变量里面吗?答案肯定是否定的,我们来看一看NullLogger

NullLogger明显是空的,那么ILogger到底是谁?怎么进入到服务中的?

LoggingModule

不知道大家对“Orchard 刨析:前奏曲”中的CachingModule还有没有印象,Orchard用了类似的机制,只不过这一次把构造函数注入变成了属性注入

在Load方法我们可以看到Orchard把一个CreateLogger委托(方法)注册成为了一个ILogger接口,也就是在服务需要(请求)类型为ILogger的服务时候会执行这个委托,这个委托会返回一个ILogger实例。

我们来看一看这个神奇的CreateLogger委托。

方法比较简单,解析一个ILoggerFactory并通过LoggerFactory为请求服务的类型创建出一个Logger

对于ILogger由谁创建的疑惑我们揭开了,但是怎么确保它是以属性输入的方式被注入进来的?下面我们接着看。

这个方法比较简单,在AttachToComponentRegistration方法中调用BuildLoggerInjectors方法生成注入的动作,并在服务被激活(服务实例创建完成后)之后执行这些委托

BuildLoggerInjectors方法稍显复杂些,但对经常使用反射的人来说很快就能看得明白。

主要的流程如下:

1.获取服务类型中所有符合约定的属性(具有Set方法必须是Public是一个实例属性类型是ILogger不具备索引参数

2.遍历这些属性

3.解析ILogger服务(实则调用CreateLogger

4.把ILogger的实例设置到该属性上。

到这边ILogger是怎么被创建的我们已经明白了,那么为什么需要NullLogger.Instance呢?

为什么需要NullLogger

其实原因很简单,日志组件不一定是必要的,也就是说在框架运行起来的时候压根我们就没有日志组件,如果没有日志组件那么在解析ILogger的时候肯定是失败的(ILogger为null),这时候如果我们在服务中使用ILogger的实例肯定是未引用对象到实例,否则就需要判断ILogger是否为null在进行日志记录,岂不麻烦。所以NullLogger.Instance的用意就在解决这个问题。

ILogger是谁?

以上我们弄明白了ILogger怎么来的下面我们来看看ILogger是谁?

首先我们来看一幅图:

ILoggerFactoryILogger这两个接口在上面我们已经知道在哪里被使用了,下面我们来看看Logging组件的具体实现部分。

不知道大家一开始看这些有没有疑惑,为什么使用了Castle Logging还要使用Log4net呢?

我们知道.net下的日志组件非常多,如:Log4net、NLog等。每一套日志组件都有部分自己特有的API,但实现的功能都大同小异,Orchard为了使API统一化而引入Castle Logging,Castle Logging并不是一个可用的日志组件,而是一套抽象的日志API

也就是说日志的记录怎么变化只要可以适配Castle Logging就可以直接与框架集成。

CastleLoggerFactory工厂中通过Castle LoggingILoggerFactory创建一个CastleLogger的实例。

那么具体的扩展就在CastleILoggerFactory中了,回顾刚才的LoggingModule

可以发现框架默认把OrchardLog4netFactory作为了CastleILoggerFactory,并且上面有一行注释,大致意思是:默认使用委托果园的日志记录器到Castle的日志记录器工厂。

到这里Logging Component的整体我们都差不多了解了。OrchardLog4netFactoryOrchardLog4netLogger就不深入的,比较简单,如果阅读还是显得比较吃力可以去Log4net官网上面去看看。

OrchardFileAppender

该类并没有在编码中出现,而是Log4net提供的一种可扩展的方式,出现在log4net.config中。具体的可以去Log4net官网上了解。

写在最后

不保证很频繁的更新本系列但保证本系列肯定会写完,最近在对一个较老的组件(系统?不知道怎么命名更贴切)以新的架构新的思想和自己的方式重新编码实现,待第一版出来之后会跟大家做分享(架构、思想上的分享)。

为了本系列的读者有更好的交流环境提供QQ群一个:299744835

Orchard 刨析:Logging的更多相关文章

  1. Orchard 刨析:导航篇

    之前承诺过针对Orchard Framework写一个系列.本应该在昨天写下这篇导航篇,不过昨天比较累偷懒的去玩了两盘单机游戏哈哈.下面进入正题. 写在前面 面向读者 之前和本文一再以Orchard ...

  2. Orchard 刨析:Caching

    关于Orchard中的Caching组件已经有一些文章做了介绍,为了系列的完整性会再次对Caching组件进行一次介绍. 缓存的使用 在Orchard看到如下一段代码: 可以看到使用缓存的方法Get而 ...

  3. Orchard 刨析:前奏曲

    Orchard中大量使用了依赖注入,而实现依赖注入的组件就是Autofac,它在Orchard中扮演者非常重要的角色,多租户如是,模块如是,工作区也如是.今天就来讲讲Autofac在Orchard中的 ...

  4. Learning Cocos2d-x for WP8(2)——深入刨析Hello World

    原文:Learning Cocos2d-x for WP8(2)--深入刨析Hello World cocos2d-x框架 在兄弟篇Learning Cocos2d-x for XNA(1)——小窥c ...

  5. MapReduce源码刨析

    MapReduce编程刨析: Map map函数是对一些独立元素组成的概念列表(如单词计数中每行数据形成的列表)的每一个元素进行指定的操作(如把每行数据拆分成不同单词,并把每个单词计数为1),用户可以 ...

  6. Apollo 刨析:Localization

    九月 30 2014 11:27 上午     admin 0 Comments 今天我们来看一看Apollo中的Localization Component. 本地化在Apollo中的使用 像这样的 ...

  7. 30s源码刨析系列之函数篇

    前言 由浅入深.逐个击破 30SecondsOfCode 中函数系列所有源码片段,带你领略源码之美. 本系列是对名库 30SecondsOfCode 的深入刨析. 本篇是其中的函数篇,可以在极短的时间 ...

  8. Golang 性能测试 (3) 跟踪刨析 golang trace

    简介 对于绝大部分服务,跟踪刨析是用不到的.但是如果遇到了下面问题,可以不妨一试: 怀疑哪个协程慢了 系统调用有问题 协程调度问题 (chan 交互.互斥锁.信号量等) 怀疑是 gc (Garbage ...

  9. 温故知新-多线程-深入刨析volatile关键词

    文章目录 摘要 volatile的作用 volatile如何解决线程可见? CPU Cache CPU Cache & 主内存 缓存一致性协议 volatile如何解决指令重排序? volat ...

随机推荐

  1. cocos2d-x之Action特效

    bool HelloWorld::init() { if ( !Layer::init() ) { return false; } Size visibleSize = Director::getIn ...

  2. 探索 OpenStack 之(12):cinder-api Service 处理 HTTP Request 的过程分析

    本文是上一篇 探索 OpenStack 之(11):cinder-api Service 启动过程分析 以及 WSGI / Paste deploy / Router 等介绍> 的后续篇. os ...

  3. 用pygame学习初级python(一) 15.4.19

    最近有计划要学一下python,主要是要用flask.django一些框架进行后端的学习工作,但是在web应用之前希望进行一些基础的项目进行一些语法的练习,熟悉一下写法, 这个时候我就想先做几个小游戏 ...

  4. selenium遇到异常自动截图

    最近要在框架中添加case失败时,要自动截图,主要又两种方式,思想都是在抛异常的时候,捕获到异常,并作页面截图处理.今天坐下总结. 一.第一种方式,重写onException方法 只针对webdriv ...

  5. IOS添加手势识别

    ios里面有手势识别,多点触控等功能,过去要实现手势识别很复杂,现在苹果为我们实现了,手势识别变得很简单 1.向视图添加手势识别器:(一般由controller完成,有时View也可以添加) 2.提供 ...

  6. HDU 5017 Ellipsoid 模拟退火第一题

    为了补这题,特意学了下模拟退火算法,感觉算法本身不是很难,就是可能降温系数,步长等参数不好设置. 具体学习可以参见: http://www.cnblogs.com/heaad/archive/2010 ...

  7. 深入.NET框架 项目《魔兽登录系统》

    创建魔兽系统相关窗体: 登录窗体(frmLogin) 注册窗体(frmRegister) 主窗体   (frmMain) 实现魔兽登录系统: 登录的界面如下 实现思路: 1.创建一个对象数组,长度为1 ...

  8. DragRigidbody2D

    组件源码 using UnityEngine; using System.Collections; //This script allows to drag rigidbody2D elements ...

  9. Android优化——UI检视利器:Hierarchy Viewer

    在Android的SDK工具包中,有很多十分有用的工具,可以帮助程序员开发和测试Android应用程序,大大提高其工作效率.其中的一款叫 Hierachy Viewer的可视化调试工具,可以很方便地在 ...

  10. Gitblit-Git版本服务器环境部署

    Gitblit介绍 Gitblit 是一个纯 Java 库用来管理.查看和处理 Git 资料库.相当于 Git 的 Java 管理工具,支持linux系统. Git是分布式版本控制系统,它强调速度.数 ...