一切福田,不離方寸,從心而覓,感無不通。

Category Archives: Programming Language

[EntLib]微软企业库5.0 学习之路——第十步、使用Unity解耦你的系统—PART2——了解Unity的使用方法(3)

     今天继续介绍Unity,在上一篇的文章中,我介绍了使用UnityContainer来注册对象之间的关系、注册已存在的对象之间的关系,同时着重介绍了Unity内置的各种生命周期管理器的使用方法,今天则主要介绍Unity的Register和Resolve的一些高级应用。 本篇文章将主要介绍: 1、注册类型同时初始化构造函数参数并重载调用。 2、注册类型同时初始化属性参数并重载调用。 3、延迟获取对象。 4、检索检索容器中注册信息。 一、注册类型同时初始化构造函数参数并重载调用      我们在使用Unity中注册对象之间的关系时,可能对象有相应的构造函数,构造函数中需要传递相应的参数,Unity就支持这样的注册,其主要靠InjectionConstructor这个类来完成,我们首先来看下具体的类构造函数:

这个构造函数有2个参数,一个字符串和一个MyClass类对象,相应的可以使用如下代码进行注册:

这样既可完成对象注册的同时对构造函数参数进行注入,此时还有另外一个需求,就是虽然在注册的时候已经对构造函数参数进行了初始化,但是在调用的时候我们想更换原先注册的值,这时应该怎么办? 在Unity中,已经帮我们解决了这个问题,我们可以通过ParameterOverride和ParameterOverrides来实现,其中ParameterOverride是针对一个参数,而ParameterOverrides是针对参数列表,有关注册参数初始化及参数重载的全部代码如下:

其中需要注意的是: 1、在使用ParameterOverride方法来重载参数时,如果注册的参数是一个具体的对象就需要使用OnType这个扩展方法来指定对应的类型,否则会报错。 2、在使用ParameterOverrides进行重载参数时,可以使用如上面代码的方式进行指定,但是同样需要使用OnType来指定,不过这个的OnType指定的类型是注册的对象类型。 效果图如下: 可以看出,其中第一个字符串参数在重载后调用时已经发生了更改。 二、注册类型同时初始化属性并重载调用     这个初始化属性和上面的初始化参数很类似,只不过不同的是,属性的注册初始化是使用InjectionProperty,而重载属性是使用的PropertyOverride和PropertyOverrides,其使用方法也是相同的,这边就不多介绍了,代码如下:

效果图如下: 可以看到2个属性都已经被重载了。 Unity还为我们提供了一个DependencyOverride重载,其使用方法和参数重载、属性重载类似,这边就不演示了,不过需要注意的是DependencyOverride是针对所注册对象类型中所包含的对象类型重载,例如在A类中有构造函数参数是B类,同时也有个属性依赖于B类,当使用了DependencyOverride后,这个A对象原先注册的有关B类的依赖将全部改变。(具体可查看示例代码中的ResolveDependency) 三、延迟获取对象     Unity还有个很不错的特性就是支持延迟获取, 其本质是通过事先建立一个委托,然后再调用这个委托,看下下面的代码:

这段代码演示了2个延迟获取的方式,都是通过将Func<T>放入Resolve<T>中来实现的,返回的是一委托,这样就可以在实际需要的时候再调用这个委托: 1、第一种是事先通过Resolve<Func<IClass>>(); 来定义获取与IClass关联的对象的委托,然后再注册IClass与MyClass之间的关系,然后再通过resolver(); 来获取。 2、第二种是事先通过Resolve<Func<IEnumerable<IClass>>>(); 来定义获取一个与IClass关联的命名实例列表的委托,然后调用相应的委托就可以一次性获取与IClass关联的所有命名实例。 这2种方式都很好的展示了Unity可以更加灵活的控制对象之间的注册与对象的调用。 四、检索容器中注册信息      当我们在不断使用Unity容器的过程中,我们有时候想看一下容器中到底注册了多少对象,以及各个对象的一些信息,如:什么对象和什么对象关联、具体的注册名称和使用的生命周期管理器,这些信息都可以在容器的Registrations属性中查看到,在Unity文档中已经有个方法来查看这些信息了,代码如下:

具体的注册代码如下:

效果图如下: 可以看到,我在代码中注册的信息都已经很好的反应出来了。 同时如果想查看某个对象是否已经被注册,可以通过container.IsRegistered<T>来验证,这边就不演示了。 以上就是本文的所有内容了,主要介绍了Unity的Register和Resolve的一些高级应用,英文好的朋友可以直接查看Unity的官方文档。 示例代码下载:点我下载 (注意:本文示例代码是基于VS2010+Unity2.0,所以请使用VS2010打开,如果没有安装VS2010,请将相关代码复制到相应的VS中运行既可) 转自:http://www.cnblogs.com/kyo-yo/archive/2010/11/22/Learning-EntLib-Tenth-Decoupling-Your-System-Using-The-Unity-PART2-Learn-To-Use-Unity-Three.html

龙生   07 Apr 2013
View Details

[EntLib]微软企业库5.0 学习之路——第十步、使用Unity解耦你的系统—PART2——了解Unity的使用方法(2)

     在前一篇文章中,我简单的介绍了如何使用代码及配置文件来进行Unity容器配置,今天则继续介绍Unity容器的使用方法。 本篇文章将主要介绍: 1、注册对象之间的关系。 2、为已存在的对象注册关系。 3、Unity中Lifetime Managers介绍。 一、注册对象之间的关系 在上一篇文章中,已经简单介绍了如何使用Unity来注册对象与对象之间的关系,通过RegisterType方法来注册对象之间的关系。 首先来看下类关系图: 有2个接口类:IClass(班级接口)和ISubject(科目接口),其分别有2个实现类,现在首先要注册班级相关的对象关系,代码如下:

这段代码展示了使用RegisterType方法来注册对象之间的关系,需要注意的是,在进行命名注册的时候,所提供的命名参数是大小写敏感的,所以输入“your”和“Your”表示的不是一个对象注册。同时这边还展示了如何通过Resolve方法来获取所需的对象,以及使用ResolveAll方法来获取与指定对象关联的所有对象列表。 有关RegisterType方法的其他重载我这边就不详细介绍了,可以点此查看详细的重载方法介绍。 接下来看下如何使用配置文件来进行配置(和上一篇的例子类似),配置文件代码如下:

二、为已存在的对象注册关系 在日常开发的过程中我们有时候会自己创建好一个对象,但是你又想对这个已经创建好的对象的生命周期进行管理,这个时候你可以使用Unity提供的RegisterInstance方法,代码示例如下:

这段代码很简单,就是通过RegisterInstance方法为已存在的对象进行注册,这样可以通过UnityContainer来管理这些对象实例的生命周期。 需要注意的是,使用RegisterInstance来将已存在的实例注册到UnityContainer中,默认情况下其实用的是ContainerControlledLifetimeManager,这个生命周期是由UnityContainer来进行管理,UnityContainer会维护一个对象实例的强引用,当你将已存在的实例注册到UnityContainer后,每次通过Resolve方法获取对象都是同一对象,也就是单件实例(singleton instance),具体有关生命周期相关信息在下面进行介绍。 由于RegisterInstance是对已存在的实例进行注册,所以无法通过配置文件来进行配置。 有关RegisterInstance方法的其他重载我这边就不详细介绍了,可以点此查看详细的重载方法介绍。 三、Unity中Lifetime Managers介绍 我们在系统中引入Unity主要就是想通过Unity来解除对象之间的依赖关系,方便我们根据配置调用到所需的对象,而Unity默认情况下会自动帮我们维护好这些对象的生命周期,可能Unity自动维护的生命周期并不是我们想要的,我们想要根据具体的需求来更改这些对象的生命周期,下面我就介绍一下Unity中内置的生命周期管理器。 1、TransientLifetimeManager,瞬态生命周期,默认情况下,在使用RegisterType进行对象关系注册时如果没有指定生命周期管理器则默认使用这个生命周期管理器,这个生命周期管理器就如同其名字一样,当使用这种管理器的时候,每次通过Resolve或ResolveAll调用对象的时候都会重新创建一个新的对象。 需要注意的是,使用RegisterInstance对已存在的对象进行关系注册的时候无法指定这个生命周期,否则会报异常。 代码如下:

配置文件如下:

如果想在配置文件中在在注册关系的时候更改一个生命周期管理器只需在<register>配置节下新增<lifetime>既可(如果不新增则默认使用TransientLifetimeManager)。 其中<lifetime>有3个参数: 1)type,生命期周期管理器的类型,这边可以选择Unity内置的,也可以使用自定义的,其中内置的生命周期管理器会有智能提示。 2)typeConverter,生命周期管理器转换类,用户自定义一个生命周期管理器的时候所创建一个转换器。 3)value,初始化生命周期管理器的值。 配置文件读取代码:

效果图如下,可以看出每次产生的对象都是不同的: 2、ContainerControlledLifetimeManager,容器控制生命周期管理,这个生命周期管理器是RegisterInstance默认使用的生命周期管理器,也就是单件实例,UnityContainer会维护一个对象实例的强引用,每次调用的时候都会返回同一对象,示例代码如下:

配置文件如下:

效果图如下,可以看出每次获取的对象都是同一对象: 3、HierarchicalLifetimeManager,分层生命周期管理器,这个管理器类似于ContainerControlledLifetimeManager,也是由UnityContainer来管理,也就是单件实例。不过与ContainerControlledLifetimeManager不同的是,这个生命周期管理器是分层的,因为Unity的容器时可以嵌套的,所以这个生命周期管理器就是针对这种情况,当使用了这种生命周期管理器,父容器和子容器所维护的对象的生命周期是由各自的容器来管理,代码如下(RegisterInstance情况也类似,这边就不展示了):

由于配置文件不能配置这种层级效果,所以配置这种生命周期时只需要更改下生命周期名称:

具体的效果图如下,可以看出父级和子级维护不同对象实例: 这边需要提一下的就是,Unity这种分级容器的好处就在于我们可以对于有不同生命周期的对象放在不同的容器中,如果一个子容器被释放,不会影响到其它子容器中的对象,但是如果根节点处父容器释放后,所有的子容器都将被释放。 4、PerResolveLifetimeManager,这个生命周期是为了解决循环引用而重复引用的生命周期,先看一下微软官方给出的实例:

从这个例子中可以看出,有2个接口IPresenter和IView,还有2个类MockPresenter和View分别实现这2个接口,同时这2个类中都包含了对另外一个类的对象属性,这个就是一个循环引用,而对应的这个生命周期管理就是针对这种情况而新增的,其类似于TransientLifetimeManager,但是其不同在于,如果应用了这种生命周期管理器,则在第一调用的时候会创建一个新的对象,而再次通过循环引用访问到的时候就会返回先前创建的对象实例(单件实例),代码如下:

从代码中可以看出,在注册对象的时候,仅对IView和View应用了PerResolveLifetimeManager,所以第二次访问View对象会返回同一实例。 具体配置文件如下,有关构造函数注入和属性注入的内容在下一篇文章中进行介绍:

读取配置文件代码类似于前面其他配置文件读取代码,这里就不展示,具体请看示例代码。 具体的效果图如下: 可以看出2次调用View对象的HashCode都是一样的,而Presenter对象的HashCode不同。 5、PerThreadLifetimeManager,每线程生命周期管理器,就是保证每个线程返回同一实例,具体代码如下:

Console.WriteLine("——-PerResolveLifetimeManager End——"); }

有关配置相关的代码与前面的生命周期管理器差不多,这边就不贴代码了,请看示例代码。 具体效果图如下: 同时需要注意的是,一般来说不建议在使用RegisterInstance对已存在的对象注册关系时使用PerThreadLifetimeManager,因为此时的对象已经在一个线程内创建了,如果再使用这个生命周期管理器,将无法保证其正确调用。 6、ExternallyControlledLifetimeManager,外部控制生命周期管理器,这个生命周期管理允许你使用RegisterType和RegisterInstance来注册对象之间的关系,但是其只会对对象保留一个弱引用,其生命周期交由外部控制,也就是意味着你可以将这个对象缓存或者销毁而不用在意UnityContainer,而当其他地方没有强引用这个对象时,其会被GC给销毁掉。 在默认情况下,使用这个生命周期管理器,每次调用Resolve都会返回同一对象(单件实例),如果被GC回收后再次调用Resolve方法将会重新创建新的对象,示例代码如下:

有关配置相关的代码与前面的生命周期管理器差不多,这边就不贴代码了,请看示例代码。 效果图如下: 以上就是本文的全部内容了,主要介绍了使用UnityContainer来注册对象之间的关系、注册已存在的对象之间的关系和Unity内置的生命周期管理器。 示例代码下载:点我下载 (注意:本文示例代码是基于VS2010+Unity2.0,所以请使用VS2010打开,如果没有安装VS2010,请将相关代码复制到相应的VS中运行既可) 转自:http://www.cnblogs.com/kyo-yo/archive/2010/11/10/Learning-EntLib-Tenth-Decoupling-Your-System-Using-The-Unity-PART2-Learn-To-Use-Unity-Two.html

龙生   07 Apr 2013
View Details

asp.net mvc2 安装后无法使用,提示“此安装不支持该项目类型”

 打开 .csproject 文件 把<ProjectTypeGuids>中的前半部分修改为:  {F85E285D-A4E0-4152-9332-AB1D724D3325};{349c5851-65df-11da-9384-00065b846f21}; 后面还有一个 GUID 是你项目的GUID 。 三个GUID 。 

龙生   03 Apr 2013
View Details

Warning: file_put_contents()

引起此问题的原因:1.数据库已经满了2.相应目录具有可读写的权限。解决方法:1.增大服务器空间。2.清理缓存目录、清空ecs_states表,目的都是为了增大可用空间。3.还有些用户经常备份数据库,这样会造成data目录下的文件占用空间。建议用户备份数据库后将备份文件保存到本地,然后将服务器上的备份文件清除。4.赋予相应的目录为可读写的权限。

龙生   03 Apr 2013
View Details

微软企业库5.0 学习之路——第十步、使用Unity解耦你的系统—PART2——了解Unity的使用方法(1)

       在上一篇文章中,我简单介绍Unity的一些背景知识、为什么要使用Unity和使用Unity有什么好处。今天将继续学习Unity,主要是了解Unity的一些常见的使用方法。 本篇文章将主要介绍: Unity中的UnityContainer基本使用介绍,包括UnityContainer类的常用方法介绍,并且通过几个小例子来介绍具体的使用方法,这些例子都会以代码及配置文件两种方式来实现。         从UnityContainer(Unity容器)这个类的名称中我们就可以看出其是Unity最重要的类,UnityContainer就像Unity的一个司令部,而一个个对象就像一名名士兵,每个士兵来去都需要通过UnityContainer来管理,其掌管了所有对象的依赖关系,所有对象的创建都会通过这个Unity容器来创建,,同时也可以说是一个外交部,对于我们开发者,我们不需要关心内部是怎么实现的,我们只需要事先设置好对象之间的关系,然后在需要的时候告诉UnityContainer我需要什么,UnityContainer就会将我们需要的直接发给我们。(这些比喻可能不正确,但是是我能想到的最好的比喻了) 使用代码实现对象关联注册: 首先来看一个简单的例子:

这个是最常见的接口及其实现类的使用方法,定义一个接口,然后再定义一个类来实现这个接口,然后在具体使用的过程中,可以通过new关键字来实例化具体来实现接口,虽然没有语法上的问题,但是这样会造成紧耦合,如果一旦具体的实现类发生了改变,则就需要修改代码,而且如果这种类似的代码很多,则会导致整个项目的变动,甚至出现异常,所以我们需要使用IOC来解耦,具体代码如下:

使用Unity来管理对象与对象之间的关系可以分为以下几步: 1、创建一个UnityContainer对象。 2、通过UnityContainer对象的RegisterType方法来注册对象与对象之间的关系。 3、通过UnityContainer对象的Resolve方法来获取指定对象关联的对象。   使用配置文件来实现对象关系注册: 以上是通过代码的方式来注册对象之间的关系,但是对于一个项目来说,正式部署后,由于代码都编译成DLL,如果要修改依赖关系则修改代码并重新编译,相对来说太麻烦了,所以Unity还提供配置文件配置的方式来配置对象之间的关系,配置如下:

具体代码调用如下:

通过配置文件配置Unity信息需要有以下几个步骤: 1、在配置文件中<configSections> 配置节下unity注册。 2、在<configuration> 配置节下添加Unity配置信息。 3、在代码中读取配置信息,并将配置载入到UnityContainer中。 使用配置文件来配置对象信息虽然可以在部署的时候更改对象之间的依赖关系,但是当系统过于复杂,则就会导致配置文件的增大,所以我们需要将Unity的配置信息从App.config或web.config中分离出来,但是这样的话前面的代码中调用方法就无效了,我们现在需要修改一下现有的代码:

由于Unity配置相对来说比较复杂,一下子难以上手,而且不像企业库的其他模块可以通过配置工具进行配置,所以p&p小组为了方便通过配置文件进行Unity配置,已经在企业库5.0的安装包中内置了UnityConfiguration20.xsd,你可以在X:\Program Files\Microsoft Visual Studio X.0\Xml\Schemas\下找到,这样就可以在配置文件中进行Unity配置时出现只能提示了,如下图: 需要注意的是,如果想出现这种提示,需要在新增的unity配置节中增加一个xmlns为http://schemas.microsoft.com/practices/2010/unity。(如果没有安装过EntLib5,所以没有UnityConfiguration20.xsd,可以在下面的示例代码中找到这个xsd。)   以上就是本文的所有内容了,主要是简单介绍一下UnityContainer的基本使用方法——如何通过代码及配置文件来实现对象之间关系,如有不对欢迎指出!   示例代码下载:点我下载 转自:http://www.cnblogs.com/kyo-yo/archive/2010/11/08/Learning-EntLib-Tenth-Decoupling-Your-System-Using-The-Unity-PART2-Learn-To-Use-Unity-One.html

龙生   01 Apr 2013
View Details

微软企业库5.0 学习之路——第九步、使用PolicyInjection模块进行AOP—PART4——建立自定义Call Handler实现用户操作日志记录

        在前面的Part3中,我介绍Policy Injection模块中内置的Call Handler的使用方法,今天则继续介绍Call Handler——Custom Call Handler,通过建立Custom Call Handler来实现项目中的用户操作日志的记录,具体的代码可以在项目中EntLib.Helper项目下找到,如下图: 本文将从Custom Call Handler两种方式来介绍:Attribute方式和Configuration方式。   一、核心代码 建立Custom Call Handler则需要有以下几个步骤: 1、建立一个类实现接口ICallHandler。 2、根据具体需求建立对应Attribute类或为Custom Call Handler实现特性[ConfigurationElementType(typeof(CustomCallHandlerData))] 首先来介绍下具体的核心代码,由于我是要实现用户的操作日志,则需要对用户的对数据的增删改以及一些特殊的操作进行记录,如:登录, 1、首先需要建立一张表用于存放用户操作记录:

2、建立一个名为UserLogCallHandler的类来实现接口ICallHandler,实现其中的方法Invoke(具体的拦截操作方法)和属性Order,具体代码如下(关键处我都写好注释了)

这段代码主要部分就是具体的Invoke方法实现,这个方法有2个参数: input,这个参数中封装了已拦截的方法、方法的参数等有用的信息 getNext,一个委托,用于调用拦截的方法,通过这个委托我们可以很好的控制我们需要在拦截了具体方法后如何进行具体的业务逻辑操作。 通过getNext()(input, getNext); 这段代码即可完成对方法的调用,这样可以根据具体需求决定在调用方法前还是方法后进行具体操作。 由于我这边是要实现一个用户操作记录,那么我要知道一些具体的信息:是谁在什么时候对什么数据做了操作,这边我需要获取3个参数:具体的操作人、操作的数据及具体描述。 首先来看下第一个参数: ◆具体的操作人,由于这个项目采用的是cookies来记录当前的登录用户,所以我可以直接从cookies中获取当前登录的人,具体可以查看代码69-71行。 ◆操作的数据,这边我在这个Call Handler中建立了一个ParameterName属性用来指定记录所拦截的方法中存放所操作数据的参数名,具体可以查看代码74-86行。 由于指定了具体的参数名,我们则需要根据参数获取具体数据值,我们来看下增删改的方法签名: int Add(Student student); bool Update(Student student); bool Delete(int id); 可以看到,我们都可以从这3个方法获取到用户具体操作的数据标识,如Student.Id和id,这样我们只需变通一下,在具体的类中,如Student中,重写ToString方法,返回具体的ID即可,代码如下:

这样,我们在Call Handler中我们就可以根据参数名获取到具体操作的数据了(如果需要详细描述具体的数据的话则需要更复杂的设计了,这边就不深入了),代码如下:

◆具体描述,这个我也是建立一个Message数据,用于存放操作的具体描述。 ◆特殊情况,当然操作日志也不可能就仅仅增删改3种情况,就比如登录,注销,这种情况则只需指定具体的消息即可,参数名无需指定,如果还有更加特殊的情况则需要根据具体需求来更改这边的设计,我这边只是给出个最基本的。   二、Attribute实现 在完成了核心代码后,我们则可以根据需求建立Attribute拦截还是Configuration拦截了。 实现Attribute拦截,需要建立一个类,实现HandlerAttribute类,实现其中的CreateHandler方法,用于调用具体的Call Handler方法,具体代码如下:

这个特性类就比较简单了,不过还需要在Call Handler中进行处理,增加一个构造函数,接收从Attribute中传递过来的参数:

  三、Configuration方式 如果要实现可以通过企业库配置工具进行配置Custom Call Handler的话,则需要对Call Handler增加一个特性: [ConfigurationElementType(typeof(CustomCallHandlerData))] 然后新增一个构造函数

完成以上2步我们就可以通过企业库配置工具进行配置了,见下图:   四、具体使用 在完成了Call Handler的代码编写和登录拦截配置后,我们就可以进行使用了,我这边更改了项目的结构,建立了一个IBLL的接口层,现有的BLL层的类则实现IBLL层中接口,而且由于Policy Injection模块要实现AOP,则具体类必须继承自MarshalByRefObject或实现一个接口(如果不清楚可以查看Part1),所以为了项目的各模块解耦、方便Policy Injection对具体类的创建和未来Unity介绍做铺垫则创建了IBLL层。(具体可以参看项目代码) 由于建立了IBLL层,则表示层的代码则需要发生变化,所有BLL层创建都需要通过PolicyInjection.Create方法来创建,具体代码如下:

这样,当我们运行代码后,进入数据库查看就可以看,操作日志已经被记录下来了。 上面说的是通过Configuration方式来进行操作日志记录,如果我们想通过Attribute方式来记录日志消息,则需要到具体的BLL层进行操作,代码如下:

注意:这边需要为项目引用Microsoft.Practices.Unity.Interception,因为Call Handler的Attribute是继承自HandlerAttribute,这个HandlerAttribute就是存放于Microsoft.Practices.Unity.Interception,否则自定义的Call Handler Attribute将无法显示出来。 这样,更新下学生信息后,我们可以就可以看到具体的操作日志了,见下图:   以上就是本文的所有内容,主要介绍了如何通过Custom Call Handler实现用户操作日志记录,如果有什么不对,欢迎大家指出,谢谢:) 至此,Policy Injection模块的介绍也结束了,下面将开始介绍企业库中使用最广泛的IOC容器——Unity,敬请期待! 转自:http://www.cnblogs.com/kyo-yo/archive/2010/10/13/Learning-EntLib-Ninth-Use-PolicyInjection-Module-AOP-PART4-Call-Handler-To-Build-User-Logging.html

龙生   01 Apr 2013
View Details

微软企业库5.0 学习之路——第九步、使用PolicyInjection模块进行AOP—PART3——内置Call Handler介绍

        在前面的Part1和Part2中我已经介绍了PolicyInjection模块的内置的Matching Rule和自定义Matching Rule的基本信息及配置使用方法,不过光有Matching Rule进行验证匹配还不够,还必须要有相应的操作——Call Handler,所以今天继续介绍PolicyInjection模块内置的Call Handler。   一、PolicyInjection模块内置的Call Handler 通过将Call Handler和Part1、Part2中的Matching Rule组合起来,我们就可以实现AOP编程,如果说Matching Rule是为了匹配寻找需要进行AOP操作的对象的话,那Call Handler则是在找到对象后进行的AOP操作。在PolicyInjection模块中内置了以下6种Call Handler: 1、Authorization Call Handler——权限操作 2、Custom Call Handler——自定义操作 3、Exception Handling Call Handler——异常处理操作 4、Logging Call Handler——日志记录操作 5、Performance Counter Call Handler——性能计数器操作 6、Validation Call Handler——验证操作 在Part1中已经介绍过,PolicyInjection模块可以和企业库中的其他模块组合起来一起使用,而内置的Call Handler也基本上都是企业库所包含的且适用于AOP编程的模块,具体的Call Handler代码可以在每个模块源码下的PolicyInjection文件夹下找到,比如:Authorization Call Handler就是在Security Application Block\PolicyInjection,主要分为:AuthorizationCallHandler.cs和AuthorizationCallHandlerAttribute.cs。   下面我介绍下这6种内置Call Handler的使用及配置方式: 二、Authorization Call Handler——权限操作 Authorization Call Handler主要和Security模块进行关联,通过这个Call Handler来调用已经配置好的Authorization Provider,主要接受3个参数: 1、Authorization Provider,指向的是所配置的具体的Authorization Provider。 2、Operation Name,验证的对象,可以是{method},{type},{namespace},{assembly}和{appdomian}。 3、Order,这个是表示被调用的次序,默认为0(如果制定了次序则将从1开始,0表示不按照次序执行)。 具体配置图如下: 相对应的如果想通过代码来实现这样的效果,需要进行以下操作: 1、引用:Microsoft.Practices.EnterpriseLibrary.Security.PolicyInjection; 2、为指定方法添加特性:[AuthorizationCallHandler("{method}-具体的验证操作名")]   三、Custom Call Handler——自定义操作 这个将在下篇文章中重点介绍   四、Exception Handling Call Handler——异常处理操作 Exception Handling Call Handler对应的是Exception Handling模块,接受的参数很简单,只有2个: 1、Expection Policy Name,指向的是具体的Exception处理策略(有关Exception相关的文章可以看学习之路——第三步、为项目加上异常处理(采用自定义扩展方式记录到数据库中))。 2、Order,同上。 具体配置图如下: 相对应的如果想通过代码来实现这样的效果,需要进行以下操作: 1、引用:Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.PolicyInjection; 2、为指定方法添加特性:[ExceptionCallHandler("Policy-具体异常策略名")]   五、Logging Call Handler——日志记录操作 Logging Call Handler对应的是Logging模块,相比前几个Call Handler,Logging Call Handler接受的参数就比较多了,有11个: 1、After/Before Message,类似于Logging模块中的消息配置中的Message Header/Footer,主要是对消息的开始和结尾处加上额外的信息,如:“--Call Handler开始—”。 2、Categories,指向的hi具体的Logging配置,(有关Logging相关的文章可以看学习之路——第三步、为项目加上异常处理(采用自定义扩展方式记录到数据库中))。 3、Event Id,事件ID,默认为0,如果有需要可以指定。 4、Include Call Stack,表示是否在日志记录消息中包含调用栈信息,默认为false,不添加调用栈信息。 5、Include Call Time,表示是否在日志记录消息中包含调用的时间,默认为true,在日志消息中添加调用时间。 6、Include Paramters Values,表示是否在日志记录消息中包含调用的方法中所传递的参数值,默认为true,在日志消息中添加参数值。 7、Log Behavior,日志行为,主要用于设置日志记录的位置,有3个枚举,BeforeAndAfter(之前和之后),Before(之前)和After(之后)。 8、Order,同上。 9、Prority,表示日志消息中异常记录的优先级,默认为-1。 10、Severity,日志级别。 具体配置图如下: 相对应的如果想通过代码来实现这样的效果,需要进行以下操作: 1、引用:Microsoft.Practices.EnterpriseLibrary.Logging.PolicyInjection; 2、为指定方法添加特性:[LogCallHandler(Categories = new string[] { "Category" })],在LogCallHandler里面还对应着许多可选参数,都可以自定义指定,如不指定则为默认值。   六、Performance Counter Call Handler——性能计数器操作 Performance Counter Call Handler与其他几个Call Handler不同,其不对应企业库的其他模块(具体代码可以在PolicyInjection\CallHandlers下找到,分别是PerformanceCounterCallHandler.cs和PerformanceCounterCallHandlerAttribute.cs) 这个Performance Counter Call Handler主要是对所拦截的策略进行性能检测,如果想使用需要以下步骤: 1、企业库配置图: 主要设置2个属性: 1)Category Name:计数器名——abc 2)Instance Name:实例名——Default 至于其他属性可以不用更改,主要是对性能监视器的一些配置。   2、安装性能计数器,需要在项目中引入:System.Configuration.Install 代码如下:

3、调用具体的方法,同时查看其性能:

在调用到InstallCounter();时在Console中会出现:这时,打开计算机管理-性能-监视工具-添加,可以看到我们刚才创建的性能计数器已经存在列表当中:添加完成后,我们就可以在性能计数器中看到我们现在所正在运行的方法的性能了:4、卸载性能计数器:

卸载后,刚才我们所安装的计数器就移除了。 以上性能计数器使用方法参考:Getting started with Enterprise Library Performance Counters     七、Validation Call Handler——验证操作 Validation Call Handler对应的是Validation模块,这个Call Handler主要接收3个参数: 1、Order,同上。 2、Rule Source,规则来源,有4个枚举可选,分别是:Both(所有来源),Attributes(特性),Configuration(配置)和ParameterAttributesOnly(仅参数特性)。 3、RuleSet,规则集,指向具体的验证配置规则集(有关Validation相关的文章可以看学习之路——第五步、介绍EntLib.Validation模块信息、验证器的实现层级及内置的各种验证器的使用方法——上篇、中篇、下篇和学习之路——第六步、使用Validation模块进行服务器端数据验证)。 具体配置图如下: 同样的Vadidation Call Handler可以不通过配置进行操作,可以直接在代码中通过特性来进行AOP。 1、首先需要引用命名空间: Microsoft.Practices.EnterpriseLibrary.PolicyInjection; Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers; Microsoft.Practices.EnterpriseLibrary.Validation.Validators; Microsoft.Practices.EnterpriseLibrary.Validation.PolicyInjection; 2、为方法添加特性:[ValidationCallHandler],然后为方法参数指定验证特性:[StringLengthValidator(6,16,MessageTemplate="输出的消息长度必须在6-16之间!")] 代码如下:

注意:如果需要在代码中使用企业库的验证模块的特性类,需要为项目添加System.ComponentModel.DataAnnotations引用。   以上就是本文的所有内容了,本文主要是对Policy Injection模块内置的Call Handler的一些配置进行简单的介绍,如果不对欢迎大家指出,下篇将主要介绍Custom Call Handler的创建及使用方法。 […]

龙生   01 Apr 2013
View Details

微软企业库5.0 学习之路——第九步、使用PolicyInjection模块进行AOP—PART2——自定义Matching Rule

         这段时间公司有新项目需要开发,所以这个企业库学习之路有点耽误了,今天继续接着上一篇文章,在上一篇文章中,我介绍了企业库的自带Matching Rule(匹配规则)的基本信息及使用方法,但是在PolicyInjection模块中的Matching Rule(匹配规则)还有2个规则没有介绍,分别是: 1、Custom Attribute Matching Rule——自定义特性匹配规则 2、Custom Matching Rule——自定义匹配规则 今天就主要对这2个匹配规则进行介绍,及有关这2个匹配规则的一些应用例子。   一、Custom Attribute Matching Rule——自定义特性匹配规则 这个匹配规则有点类似于Tag Attribute Matching Rule,只不过Tag Attribute Matching Rule已经定死了特性类——TagAttribute,具体匹配需要靠TagAttribute特性类的tag字符串来标识具体的策略名,使用起来不怎么方便,而且使用字符串来标识,可能会写错,不过企业库同样为我们预留了扩展接口,就是这个自定义特性匹配规则——Custom Attribute Matching Rule。 这个匹配规则使用起来很简单,只需自己定义个特性类,然后在企业库配置工具中进行配置既可。 这个匹配规则接收2个参数:Attribute Type Name和Search Inheritance Chain 1、Attribute Type Name,这个意思很明确了,就是特性类的名称,只需点击旁边的选择按钮即可选择到自己定义的特性类。 2、Search Inheritance Chain,这个是表示是否要查询继承关系,默认为false,表示不查询,看下面的代码就可以理解了: 我首先定义了一个自定义的特性类:

然后在应用到代码中:

可以看到我将MyCustomAttribute应用到了抽象类CustomAttrTest中的抽象方法CwInfo上,然后由子类ChildCustomerAttrTest来实现,如果将Search Inheritance Chain设置为false,则在方法调用的过程中将不会被拦截,因为MyCustomAttribute是应用在抽象类中,而不是应用在实现类中,所以如果想依靠抽象类来定义拦截,则需要将Search Inheritance Chain设置为true。 具体配置图如下:   注:由于PolicyInjection模块的一个BUG问题,在通过PolicyInjection创建对象的时候,如果创建的对象需要指向一个抽象类将会报错,代码如下:

具体的问题,可以参考Artech写的这篇文章:这是EnterLib PIAB的BUG吗?,里面介绍了这个问题的产生原因及解决办法。   通过Custom Attribute Matching Rule我们可以根据我们自己的具体需求自由建立特性类,比如:异常、权限、日志等等,通过自己来建立特性类,这样我们可以很好的分隔各个功能,在具体的时候过程中我们可以自由组合所需要的功能,如下代码: 我首先定义几个需要使用的特性类:

然后为每个特性类关联不同处理操作: 最后使用的时候只需根据需要自己为方法添加特性既可:

  二、Custom Matching Rule——自定义匹配规则 如果企业库内置的那么多匹配规则都无法达到你想要的话,你可以尝试着自己编写匹配规则,当然企业库也预留了这个接口,就是Custom Matching Rule。如果要自己实现一个Custom Matching Rule,主要分为2步: 1、建立一个类继承自接口IMatchingRule(这个接口是属于Microsoft.Practices.Unity.InterceptionExtension,需要引用Unity.dll),并实现方法bool Matches(System.Reflection.MethodBase member)。 2、为类加上特性[ConfigurationElementType(typeof(CustomMatchingRuleData))](需要引用命名空间Microsoft.Practices.EnterpriseLibrary.Common.Configuration和Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration),标识其继承自CustomMatchingRuleData,可以被企业库配置工具识别到。 代码如下:

配置图如下: 这样就可以在Matches方法中编写匹配方法,我这边写了个简单匹配,对根据方法名进行匹配。 这个匹配是通过配置工具中配置的方法名进行匹配,如果配置的方法名和所调用的方法名相同则返回匹配成功。这里需要注意的是,如果想要在自己实现的自定义匹配类获取到配置工具中所定义的配置,需要定义一个构造函数,接收类型为NameValueCollection的参数,我这边就通过在类中定义一个attributes参数来接收配置工具中所配置的参数,然后在Matches方法中进行处理。   以上就是本文的所有内容,本文主要介绍了自定义特性匹配规则和自定义匹配规则的创建及使用方法,如有不对之处欢迎大家指出:) 转自:http://www.cnblogs.com/kyo-yo/archive/2010/09/20/Learning-EntLib-Ninth-Use-PolicyInjection-Module-AOP-PART2-Custom-Matching-Rule.html

龙生   01 Apr 2013
View Details

微软企业库5.0 学习之路——第九步、使用PolicyInjection模块进行AOP—PART1——基本使用介绍

       继续微软企业库5.0的学习之路,今天主要介绍的是企业库的PolicyInjection模块,这个模块是为了方便我们在项目中使用AOP而生的模块,本篇主要介绍的PolicyInjection模块信息、内置的匹配规则和内置处理模块使用。   一、PolicyInjection模块基本信息介绍 PolicyInjection模块是在企业库3.0才正式引入的模块,简称PIAB(Policy Injection Application Block),这个模块的主要功能是方便我们在项目开发中进行AOP(面向切面编程),以简化开发内容。有关AOP方面的知识在园子里已经有很多朋友介绍过了,我这边就不重复介绍了,如不了解的朋友可以到张逸的这篇文章中学习:AOP技术基础。 在.NET下其实已经有很多成熟的AOP项目,比如:PostSharp、Spring.net、Jboss等等,而我今天介绍的企业库的PIAB同样也是实现AOP功能,但是PIAB可以和企业库中的其它几大模块,如Logging(日志)、Exception(异常)、Security(权限)等进行很好的合并,只需简单的配置立刻可以实现AOP功能。 由于在国内对PIAB的文章比较少,所以想深入的朋友可以看下Artech写的《EnterLib PIAB深入剖析》系列博文(不过Artech写的比较早,是08年写,当时的企业库版本还是3.1的版本,所以与现在的企业库5.0版本已经有许多不同的地方,不过其原理并没有变,值得一看) 如果想了解PIAB在企业库配置工具怎么配置以及基本使用方法可以看看huangcong写的这篇:Policy Injection Application Block 上图就是PolicyInjection模块的配置图,从图中的图示就可以看出,中间是具体的AOP策略,左边是这个AOP策略所要的验证规则,而右边则是这个AOP策略的具体调用处理操作。 注意: 1、每个策略配置所使用的验证规则最好只使用一个,如果使用一个以上则会出现AOP效果无法实现。 2、需要实现AOP策略的类必须实现类MarshalByRefObject或这个类必须实现一个接口   二、PolicyInjection模块内置验证规则使用介绍 PolicyInjection模块继承了企业库优秀的易用性和扩展性,与其他几大模块一样,其内置了许多常用的验证规则已方便我们开发人员的使用,主要有以下11种验证规则: 1、Assembly Matching Rule——程序集验证规则 2、Custom Attribute Matching Rule——自定义特性验证规则 3、Custom Matching Rule——自定义验证规则 4、Member Name Matching Rule——名称验证规则 5、Method Signature Matching Rule——方法签名验证规则 6、Namespace Matching Rule——命名空间验证规则 7、Parameter Type Matching Rule——参数类型验证规则 8、Property Matching Rule——属性验证规则 9、Return Type Matching Rule——返回类型验证规则 10、Tag Attribute Matching Rule——Tag特性验证规则 11、Type Matching Rule——类型验证规则   下面我详细介绍一下这些内置验证规则的使用方法: 1、Assembly Matching Rule——程序集验证规则 这个验证是对程序集名进行匹配,已达到AOP的效果,这个验证规则只接收一个参数:Assembly Name。 这个参数Assembly Name可接收的字符串类型有以下几种: 1、name and version,名称和版本号 如:Microsoft.Practices.EnterpriseLibrary.Common, Version=5.0.414.0 2、name、version and curlture,名称、版本号和Culture 如:Microsoft.Practices.EnterpriseLibrary.Common, Version=5.0.414.0,Culture=neutral 3、full assembly name,程序集的全名,但是不能包含“.dll”后缀名 如:AOPAssembly   2、Custom Attribute Matching Rule——自定义特性验证规则 和 Custom Matching Rule——自定义验证规则 这2个验证是为开发者预留的,有关这2个验证规则我在下一篇文章中进行介绍。   3、Member Name Matching Rule——名称验证规则 这个验证规则也比较简单,对符合配置名称的类或类成员进行验证,这个验证规则只接收一个参数:Member Names(支持通配符) 见下面的代码,我想在执行Test方法的时候进行AOP策略,只需将类继承MarshalByRefObject,然后在企业库配置工具进行配置,添加Member Name Matching Rule,将Test方法名添加到配置工具中:

配置图如下: 4、Method Signature Matching Rule——方法签名验证规则 这个验证规则比较特殊,是根据方法签名进行AOP策略,方法签名的一般为:Test(string aa) 这个验证规则接收2个参数: 1、Match,匹配的方法名,这个Match可以接收通配符匹配,“*”(表示多个字符),“?”(表示零个或一个字符),“[]”(通过在[]中书写字符范围) 如: Test*,支持Testa,Testab等方法名的匹配 Test?,支持Test,Testa等方法名的匹配 Test[1-9],支持Test1,Test2等方法名的匹配 2、Parameters,方法参数列表,需要制定参数名称和参数类型 需要注意的是,参数类型最好不要从配置工具旁边的“类型选择器”,因为通过这个类型选择器选择的参数类型会包含程序集的版本号等无用信息,会导致AOP策略失败,所以建议手写类型。 如:Name:aa,Parameter Type Name:System.String 实例代码如下:

配置图如下:   5、Namespace Matching Rule——命名空间验证规则 这个验证规则类似于上面的Member Name Matching Rule,只不过Namespace Matching Rule是匹配命名空间验证,这个验证规则接收一个参数:Namespaces(支持通配符) 这个参数Namespaces是一个集合,可以配置需要进行AOP策略的命名空间 如:AOPAssembly.Test 需要注意的是,如果需要进行匹配的命名是不是根级命名空间,比如:AOPAssembly.Test,那么不能仅仅写根命名空间AOPAssembly,这样将会匹配不到。 配置图如下:   6、Parameter Type Matching Rule——参数类型验证规则 这个验证是对方法参数进行匹配,接收一个参数Parameters Type 这个参数Parameters Type也是一个集合,可以配置需要进行AOP策略的参数信息 这个Parameters Type主要有2个子参数:Parameter Kind(参数方向,有Input,Output,InputOrOutput和ReturnValue5种类型)和Match(匹配名) 如:Parameter Kind:Input,Match:bb 示例代码如下:

配置图如下:   7、Return Type Matching Rule——返回类型验证规则 这个类型验证规则是根据方法返回值的类型进行匹配,接收一个参数Return Type 这个Return Type可以是类型名,也可以使类名 如:System.String,Class1 示例代码如下:

配置图如下:   8、Tag Attribute Matching Rule——Tag特性验证规则 这个验证规则是根据特性(Attribute)——TagAttribute来进行验证的,这个验证规则接收一个参数:Tag Attribute。 这个参数Tag Attribute是接收配置在类、方法或属性的特性参数(支持通配符)。 […]

龙生   01 Apr 2013
View Details

微软企业库5.0 学习之路——第八步、使用Configuration Setting模块等多种方式分类管理企业库配置信息

        在介绍完企业库几个常用模块后,我今天要对企业库的配置文件进行处理,缘由是我打开web.config想进行一些配置的时候发现web.config已经变的异常的臃肿(大量的企业库配置信息充斥其中),所以决定写这篇关于Configuration Setting模块等其他方式分类管理企业库配置信息的文章。 在ASP.NET4中微软就帮我们优化过了web.config,给了我们一个干净的web.config(将原来需要通过web.config注册的程序集、ASP.NET标签和handler等都移至machine.config中)这样大大方便了我们开发人员。 虽然我们通过企业库的配置工具可以很方便的配置企业库信息,但是如果要在web.config中修改其他信息就麻烦了,而且企业库的各模块信息也都在一起不利于日后的维护,所以我们首先就要把企业库的配置信息给剥离出来,然后再根据各模块分成一个一个独立的.config配置文件,统一放在一个文件夹中,这样项目发布后再修改配置信息时也可以立刻找到需要配置的文件。 分离配置文件的方式主要有3种,这3种方式各有优势也各有劣势,主要还是看实际如何应用: 1、使用企业库提供的Configuration Setting(只需配置无需修改代码,分离出的模块无法直接统一查看,只能查看单独模块,推荐) 2、分离出独立config文件或使用编码的形式来读取配置文件(必须编写代码,使用起来较为麻烦,分离出的模块无法直接统一查看只能查看单独模块,不推荐) 3、使用.NET的configSource特性进行配置(无需企业库工具配置,只需分离代码,分离出的模块可以统一查看,但是修改配置文件后所有配置信息又会重新回到web.config中,同时无法修改分离出去的单独配置文件,推荐)   一、使用企业库中默认已经提供了Configuration Setting模块来进行配置: 1、首先将各模块的信息先分离成一个一个单独的config文件(包括这个模块的section以及具体的配置)如下(Data Access模块配置文件):

2、在企业库中添加一个Configuration Setting模块,然后选择添加一个Filed-Based Configuration Source,将路径选择为刚才所分离好的config配置文件,同时建立一个重定向设置,设置到相对应的企业库模块: 添加Filed-Based Configuration Source 指向配置文件并建立重定项模块     这样项目中有几个企业库模块就建立几个相对应的配置文件,而且不需要修改任何代码。   二、使用编码形式来进行配置: 这种方式使用的配置文件同第一种方式,在配置文件中需要包含section等模块的配置信息,然后在具体使用企业各模块的时候采用如下代码:

这种方式我个人认为很不方便,每次使用企业库中的模块时候首先要通过FileConfigurationSource 来获取这个模块具体的配置信息,然后才能创建实例对象,如果一旦配置文件名称发生改变将会出现异常,所以并不推荐使用这种方式来管理配置信息   三、使用.NET的configSource特性进行配置: 这种方式的好处是显而易见的,就是不用在企业库中添加Configuration Setting,只需单独建立config文件,然后把所需的配置信息剪切到config文件中即可,但是有几点需要注意: 1、有关企业库模块的section信息必须放在web.config中 2、在单独放置的config文件应该是一个干净的XML文件,不能包含有<configuration>配置节,仅仅需要某个模块的配置即可 3、在web.config中必须保留一句指向config的配置节 虽然这种方式操作最善但是缺点也很突出,就是一旦通过企业库配置工具修改过web.config,企业库的所有配置信息又会在web.config中重新产生,同时无法单独编辑分离出去的单独的config文件 具体配置如下: web.config:

CacheConfig.config:

这样便完成了配置,代码中无需进行任何更改,同时在企业库的配置工具中可以查看具体的配置信息,唯一不好的就是一旦你用企业库的配置工具打开过web.congfig文件后,所有分离到各个配置文件中的配置信息又回重新返回到web.config中,可以说是有利有弊。   以上三种就是企业库配置信息的分类处理方式,总的来说推荐使用顺序是:第一种>第三种>第二种。不过具体的方式还是要根据各种使用需求情况进行选择。   源代码下载:点我下载   注意: 1、MSSQL数据库在DataBase目录下(需要自行附加数据库),SQLite数据库在Web目录的App_Data下,由于考虑到项目的大小,所以每个项目的BIN目录都已经删除,如出现无法生成项目请自行添加相关企业库的DLL。 2、由于微软企业库5.0 学习之路这个系列我是准备以一个小型项目的形式介绍企业库的各模块,所以源代码会根据系列文章的更新而更新,所以源代码不能保证与文章中所贴代码相同。 3、项目开发环境为:VS2010+SQL2005。 4、管理员帐户:admin               密码:admin 转自:http://www.cnblogs.com/kyo-yo/archive/2010/08/16/Learning-EntLib-Eighth-Use-Configuration-Setting-To-Manage-ConfigInfo.html

龙生   01 Apr 2013
View Details
1 155 156 157 175