Orchard學習 0一、orchard日誌

1、日誌模塊類圖app

一、ILogger接口及實現
二、ILoggerFactory接口及實現
三、其餘
2、NullLogger類型
    NullLogger類型是實現ILogger接口的空類型。它的 IsEnabled 方法老是返回false;Log 方法是個空實現。在代碼中要用到日誌的地方設計1個  NullLogger屬性 做爲佔位符,在代碼運行時將這個對象替換爲真正的日誌對象。若是不替換,則代碼也能編譯成功,運行時也不會出錯。
 1 publicclassNullLogger:ILogger
 2 {
 3 privatestaticreadonlyILogger _instance =newNullLogger();
 4 publicstaticILoggerInstance
 5 {
 6  get
 7 {
 8 return _instance;
 9 }
10 }
11 #region ILogger 成員
12 
13 public bool IsEnabled(LogLevel level)
14 {
15 returnfalse;
16 }
17 
18 publicvoidLog(LogLevel level,Exception exception,string format,paramsobject[] args)
19 {
20 
21 }
22 
23 #endregion
24 }
View Code

 

3、和autofac的結合使用
    在orchard中,autofac的使用無處不在。日誌模塊也不例外。前面說過, NullLogger 類型至關於1個日誌類型的佔位符,在運行時能夠被替換爲真實的日誌類型。那在運行時如何替換呢?這就要和autofac結合在一塊兒使用
一、LoggingModule類
    LoggingModule類繼承了Module類型。Module類型是autofac的類型。
 1 publicclassLoggingModule:Module
 2 {
 3 privatereadonlyConcurrentDictionary<string,ILogger> _loggerCache;
 4 
 5 publicLoggingModule()
 6 {
 7  _loggerCache =newConcurrentDictionary<string,ILogger>();
 8 }
 9 
10 protectedoverridevoidLoad(ContainerBuilder moduleBuilder)
11 {
12 // by default, use Orchard's logger that delegates to Castle's logger factory
13  moduleBuilder.RegisterType<CastleLoggerFactory>().As<ILoggerFactory>().InstancePerLifetimeScope();
14  moduleBuilder.RegisterType<OrchardLog4netFactory>().As<Castle.Core.Logging.ILoggerFactory>().InstancePerLifetimeScope().WithParameter(newNamedParameter("isFullTrust",false));
15 
16 // call CreateLogger in response to the request for an ILogger implementation
17  moduleBuilder.Register(CreateLogger).As<ILogger>().InstancePerDependency();
18 }
19 
20 protectedoverridevoidAttachToComponentRegistration(IComponentRegistry componentRegistry,IComponentRegistration registration)
21 {
22 var implementationType = registration.Activator.LimitType;
23 
24 // build an array of actions on this type to assign loggers to member properties
25 var injectors =BuildLoggerInjectors(implementationType).ToArray();
26 
27 // if there are no logger properties, there's no reason to hook the activated event
28 if(!injectors.Any())
29 return;
30 
31 // otherwise, whan an instance of this component is activated, inject the loggers on the instance
32  registration.Activated+=(s, e)=>
33 {
34 foreach(var injector in injectors)
35  injector(e.Context, e.Instance);
36 };
37 }
38 
39 privateIEnumerable<Action<IComponentContext,object>>BuildLoggerInjectors(Type componentType)
40 {
41 // Look for settable properties of type "ILogger" 
42 var loggerProperties = componentType
43 .GetProperties(BindingFlags.SetProperty|BindingFlags.Public|BindingFlags.Instance)
44 .Select(p =>new
45 {
46 PropertyInfo= p,
47  p.PropertyType,
48 IndexParameters= p.GetIndexParameters(),
49 Accessors= p.GetAccessors(false)
50 })
51 .Where(x => x.PropertyType==typeof(ILogger))// must be a logger
52 .Where(x => x.IndexParameters.Count()==0)// must not be an indexer
53 .Where(x => x.Accessors.Length!=1|| x.Accessors[0].ReturnType==typeof(void));//must have get/set, or only set
54 
55 // Return an array of actions that resolve a logger and assign the property
56 foreach(var entry in loggerProperties)
57 {
58 var propertyInfo = entry.PropertyInfo;
59  yield return(ctx, instance)=>
60 {
61 string component = componentType.ToString();
62 if(component != instance.GetType().ToString())
63 {
64 return;
65 }
66 var logger = _loggerCache.GetOrAdd(component, key => ctx.Resolve<ILogger>(newTypedParameter(typeof(Type), componentType)));
67  propertyInfo.SetValue(instance, logger,null);
68 };
69 }
70 }
71 
72 privatestaticILoggerCreateLogger(IComponentContext context,IEnumerable<Parameter> parameters)
73 {
74 // return an ILogger in response to Resolve<ILogger>(componentTypeParameter)
75 var loggerFactory = context.Resolve<ILoggerFactory>();
76 var containingType = parameters.TypedAs<Type>();
77 return loggerFactory.CreateLogger(containingType);
78 }
79 }
View Code

 

    
1)   L oad方法在 builder.Build()時會被調用,這裏註冊了 3個類型
moduleBuilder.RegisterType<CastleLoggerFactory>().As<ILoggerFactory>().InstancePerLifetimeScope();
 
moduleBuilder.RegisterType<OrchardLog4netFactory>().As<Castle.Core.Logging.ILoggerFactory>().InstancePerLifetimeScope().WithParameter(new NamedParameter("isFullTrust", false));
      
moduleBuilder.Register(CreateLogger).As<ILogger>().InstancePerDependency();
 
2) AttachToComponentRegistration方法也會在  builder.Build()時會被調用,它會調用BuildLoggerInjectors 方法。而 BuildLoggerInjectors方法會檢查 類型 中的屬性,若是屬性是 ILogger接口,則會被替換爲 CastleLogger或 OrchardLog4netLogger類。固然你也能註冊爲自定義的其餘日誌類型。
 
4、log4net 設置
    orchard使用 log4net做爲日誌的具體實現。配置以下
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <log4net>
 3 <root>
 4 
 5 <priority value="ERROR"/>
 6 <appender-refref="error-file"/>
 7 </root>
 8 
 9 
10 <logger name="NHibernate.Cache">
11 <priority value="ERROR"/>
12 </logger>
13 
14 <logger name="NHibernate.AdoNet.AbstractBatcher">
15 <priority value="ERROR"/>
16 </logger>
17 
18 <logger name="NHibernate.Util.ADOExceptionReporter">
19 <priority value="ERROR"/>
20 </logger>
21 
22 <appender name="error-file" type="Orchard.Logging.OrchardFileAppender">
23 <file value="orchard-error"/>
24 <appendToFile value="true"/>
25 <immediateFlush value="false"/>
26 <staticLogFileName value="false"/>
27 <rollingStyle value="Date"/>
28 <datepattern value="-yyyy.MM.dd'.log'"/>
29 <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
30 <layout type="log4net.Layout.PatternLayout">
31 <conversionPattern value="%date [%thread] %logger - %P{Tenant} - %message%newline %P{Url}%newline"/>
32 </layout>
33 </appender>
34 </log4net>
View Code

 

 
 
5、orchard日誌模塊使用示例
一、要使用日誌的類型
  1.  1 /// <summary>
     2 /// 要使用日誌的類型
     3 /// </summary>
     4 publicclassThing
     5 {
     6 publicThing()
     7 {
     8 Logger=NullLogger.Instance;
     9 }
    10 /// <summary>
    11 /// 設置類型爲 ILogger 的屬性
    12 /// </summary>
    13 publicILoggerLogger
    14 {
    15  get;
    16 set;
    17 }
    18 publicvoidTestMethod()
    19 {
    20 //這使用Log方法則 Logger屬性 會被設置爲 CastleLogger類;使用Error方法 Logger屬性 會被設置爲OrchardLog4netLogger類
    21 Logger.Log(Orchard.Logging.LogLevel.Error,newException("測試異常"),"測試異常使用CastleLogger類型");
    22 Logger.Error(newException("測試異常"),"測試異常使用OrchardLog4netLogger類型");
    23 }
    24 }
    View Code

     

二、調用
  1. 1 publicvoidCreateTest()
    2 {
    3 var builder =newContainerBuilder();//構建autofac容器
    4 builder.RegisterModule(newLoggingModule());//註冊LoggingModule
    5  builder.RegisterType<Thing>();//註冊 Thing類型
    6 var container = builder.Build();//Build 容器
    7 var thing = container.Resolve<Thing>();//從容器中解析 Thing類型
    8 thing.TestMethod();//調用TestMethod方法,則會調用日誌
    9 }
    View Code

     

 
 
    
 
 

 



相關文章
相關標籤/搜索