| Tony Huang's profileSouline PLUS planBlogListsNetwork | Help |
|
21 December 一些常用组件的用法今天要用一些常用的组件,但是却忘记了具体的做法,在网上找了好久才,找到,就干脆在自己博客上记录一下,以后用起来方便一点吧。
1) Log4net 的配置和使用
配置:
<?xml version="1.0" encoding="utf-8" ?>
<log4net> <root> </root> <logger name="CallLog"> <level value="ALL" /> <appender-ref ref="CallLogAppender" /> </logger> <appender name="CallLogAppender" type="log4net.Appender.FileAppender"> <param name="File" value="E:\logs\World\CallLog.log" /> <param name="AppendToFile" value="true" /> <param name="RollingStyle" value="Date" /> <param name="DatePattern" value="yyyy-MM-dd HH:mm:ss" /> <param name="StaticLogFileName" value="false" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%d [%t] %-5p %c - %m%n" /> </layout> </appender> </log4net> 具体的内容我也不解释,大家就将就着看吧,参考类的东西,就不用那么详尽了,呵呵
初始化:
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.Load(AppDomain.CurrentDomain.BaseDirectory + "log4net.config.xml"); log4net.Config.XmlConfigurator.Configure(doc.DocumentElement); 使用:
var log = log4net.LogManager.GetLogger("CallLogger");
log.DebugFormat("{0}.{1} called", className, methodName);
2、Castle.Windsor.WindsorContainer
常用的轻量级IoC容器。
配置:
<?xml version="1.0" encoding="utf-8" ?>
<configuration> <components> <!-- WebServiceManager --> <component id="WebServiceManager" service="Souline.Basic.Facility.WebServiceManager, Souline.Basic.Facility" type="Souline.Basic.Facility.WebServiceManager, Souline.Basic.Facility"> <parameters> <services> <item type="System.String"> <item>Souline.World.WebService.LoginService, Souline.World.WebService</item> </item> </services> </parameters> </component> <!-- Logger --> <component id="CallLogger" service="Souline.Basic.Contract.ILogService, Souline.Basic.Contract" type="Souline.Basic.Facility.Log4netLogService, Souline.Basic.Facility"> <parameters> <loggerName>CallLog</loggerName> </parameters> </component> <component id="CallLoggerInterceptor" type="Souline.Basic.Facility.Interceptor.LogServiceInterceptor, Souline.Basic.Facility"> <parameters> <logService>${CallLogger}</logService> <logLevel>Debug</logLevel> <format>{datetime} [{pid}:{tid}] {class} : {method} > {message}</format> </parameters> </component> <!-- LoginService --> <component id="LoginServiceCache" service="Souline.Basic.Contract.ICacheService`2[[System.String], [System.Object]], Souline.Basic.Contract" type="Souline.Basic.Facility.LocalMemoryCacheService`2[[System.String], [System.Object]], Souline.Basic.Facility"> </component> <component id="LoginService" service="Souline.Basic.Contract.ILoginService, Souline.Basic.Contract" type="Souline.Basic.LoginService, Souline.Basic"> <parameters> <userCache>${LoginServiceCache}</userCache> </parameters> <interceptors> <interceptor>${CallLoggerInterceptor}</interceptor> </interceptors> </component> </components> <facilities> <facility id="factorysupport" type="Castle.Facilities.FactorySupport.FactorySupportFacility, Castle.MicroKernel" /> </facilities> </configuration> 初始化:
_container = new WindsorContainer(new Castle.Windsor.Configuration.Interpreters.XmlInterpreter(containerConfig));
使用:
var loginService = _container.GetService<Souline.Basic.Contract.ILoginService>();
3、Castle.ActiveRecord
配置:
<?xml version="1.0" encoding="utf-8" ?>
<activerecord> <config> <add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" /> <add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2000Dialect" /> <add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" /> <add key="hibernate.connection.connection_string" value="Data Source=.;Initial Catalog=World;Integrated Security=True;" /> </config> </activerecord> 初始化:
Castle.ActiveRecord.ActiveRecordStarter.Initialize(
new Castle.ActiveRecord.Framework.Config.XmlConfigurationSource( AppDomain.CurrentDomain.BaseDirectory + "Castle.ActiveRecord.config.xml"), typeof(Souline.Basic.Entity.User)); 实体类:
namespace Souline.Basic.Entity
{ [ActiveRecord("Basic_Login_User")] public class User : ActiveRecordBase<User> { [PrimaryKey] public virtual int Id { get; set; } [Property]
public virtual string Username { get; set; } [Property]
public virtual string PasswordHash { get; set; } [Property]
public virtual string Type { get; set; } [Property]
public virtual string Status { get; set; } public static Entity.User FindByUsername(string username)
{ Entity.User[] users = FindAllByProperty("Username", username); if (users.Length == 0)
return null; else return users[0]; } } } 用法:
直接使用 Entity.User类就好了
19 December 关于AOP和IoCAOP是最近非常热门的词,全称叫作Aspect-oriented Programming,一直以来,我对这个名词的理解就是模模糊糊的。
知道最近在一个项目中,思考Log模块和Cache模块的设计的时候,才使我恍然大悟,原来AOP就是这么简单、自然的概念。
所谓的AOP就是希望程序员在编写程序的时候,能够完全关注在应用逻辑本身,而不用去考虑与逻辑本身无关的Facility的东西。我们拿那个经典的取钱的例子为例:
假设现在有一个
Account类,它保存的是用户帐户的余额:
这时,程序员关注的流程是,Deposit和Withdraw本身,诸如校验余额啦,修改余额啦什么的。 这时项目经理过来跟架构师说,我们的客户是银行,需要将所有的调用记录都保存下来备案,保证数据的安全。 但是现在的架构如果需要添加这个功能,则必须在每个方法的开头、结束等处加上日志相关的代码,但这势必造成工作量快速变大。那么AOP是如何解决这个矛盾的呢? 那么让我们回头来思考这个问题: 我们分析一下项目经理的要求是: 对所有的操作,都要记录日志,能够反映程序中的热点代码、瓶颈和发生的错误 关键就是所有和操作两个词,让我们回想一下Dynamic Proxy的功能: 拦截某类的所有方法调用,并插入执行代码 是不是刚好和我们的需求有匹配的地方呢? 经过修改的Account类变成了这个样子:
利用DynamicProxy类动态的生成一个继承自Account 类的类,并重写(override)它的所有方法,加入拦截的函数。再编写LogIntercepter类,记录所有的调用信息。 这就是AOP。我们没有修改原有的代码(基本没有,除了virtual关键字),但是却加入了某一方面(aspect)的功能。
那么我为什么要把AOP和IoC一起讲呢,因为他们之间有着密不可分的联系,我以.Net平台下的Castle库中的Windsor/MicroKernel容器为例。它提供了一个轻量级的IoC容器,提供了一种方便的方式配置组建和拦截器,基于配置的实现AOP的功能。具体的做法,我在下一篇文章中再写吧,有点晚了,去睡觉咯~ 01 December 一种有关锁的设计模式今天看了一个ThreadSafeDictionary的代码,从里面看到了一个很好的使用锁的设计模式,首先从使用开始说:
public void Set(TKey key, TKey value)
{
using(new WriterLock(this._lock))
{
// do something
}
}
然后再看看WriterLock的实现:
class WriterLock : IDispose
{
private ReaderWriterLockSlim _lock;
public WriterLock(ReaderWriterLockSlim lock)
{
_lock = lock;
_lock.GetWriterLock(lock);
}
public Dispose()
{
_lock.ReleaseWriterLock(_lock);
}
}
他的作用机理是什么呢?
首先我们从using开始看,using语句中包含了一个new语句,这就调用了WriterLock中的ctor,也就是给目标加锁,而当需要保护的代码结束的时候,也就是using块之外的时候,这个新创建的对象已经不再生存期内,所以就自动调用了WriterLock中的Dispose方法。
这是非常值得借鉴的一种设计模式,在NHibernate和Castle.ActiveRecord中也有广泛的应用,比如:
using(new SessionScope())
{
// do something
}
using(new Transaction())
{
// do something
} |
|
|