Microsoft.Practices.ServiceLocation 之 动态单例模式
Microsoft.Practices.ServiceLocation 之 动态单例模式
背景
框架开发中,经常会用到“单例模式”,但是传统的单例模式不支持多态和运行时变化,在关注测试的今天,这种模式是不可行的。为了应对这种情况,微软又提供了另外一种模式,暂且将其称为“动态单例模式”。 我也想统一我的框架对单例的使用模式,因此就写了这篇文章。
Microsoft.Practices.ServiceLocation 核心代码
看完代码,如何使用这种模式就不用我多介绍了。
IServiceLocator
View Code
1 using System; 2 using System.Collections.Generic; 3 4 namespace Microsoft.Practices.ServiceLocation 5 { 6 /// <summary> 7 /// The generic Service Locator interface. This interface is used 8 /// to retrieve services (instances identified by type and optional 9 /// name) from a container. 10 /// </summary> 11 public interface IServiceLocator : IServiceProvider 12 { 13 /// <summary> 14 /// Get an instance of the given <paramref name="serviceType"/> . 15 /// </summary> 16 /// <param name="serviceType"> Type of object requested. </param> 17 /// <exception cref="ActivationException"> if there is an error resolving 18 /// the service instance. </exception> 19 /// <returns> The requested service instance. </returns> 20 object GetInstance(Type serviceType); 21 22 /// <summary> 23 /// Get an instance of the given named <paramref name="serviceType"/> . 24 /// </summary> 25 /// <param name="serviceType"> Type of object requested. </param> 26 /// <param name="key"> Name the object was registered with. </param> 27 /// <exception cref="ActivationException"> if there is an error resolving 28 /// the service instance. </exception> 29 /// <returns> The requested service instance. </returns> 30 object GetInstance(Type serviceType, string key); 31 32 /// <summary> 33 /// Get all instances of the given <paramref name="serviceType"/> currently 34 /// registered in the container. 35 /// </summary> 36 /// <param name="serviceType"> Type of object requested. </param> 37 /// <exception cref="ActivationException"> if there is are errors resolving 38 /// the service instance. </exception> 39 /// <returns> A sequence of instances of the requested <paramref name="serviceType"/> . </returns> 40 IEnumerable< object > GetAllInstances(Type serviceType); 41 42 /// <summary> 43 /// Get an instance of the given <typeparamref name="TService"/> . 44 /// </summary> 45 /// <typeparam name="TService"> Type of object requested. </typeparam> 46 /// <exception cref="ActivationException"> if there is are errors resolving 47 /// the service instance. </exception> 48 /// <returns> The requested service instance. </returns> 49 TService GetInstance<TService> (); 50 51 /// <summary> 52 /// Get an instance of the given named <typeparamref name="TService"/> . 53 /// </summary> 54 /// <typeparam name="TService"> Type of object requested. </typeparam> 55 /// <param name="key"> Name the object was registered with. </param> 56 /// <exception cref="ActivationException"> if there is are errors resolving 57 /// the service instance. </exception> 58 /// <returns> The requested service instance. </returns> 59 TService GetInstance<TService>( string key); 60 61 /// <summary> 62 /// Get all instances of the given <typeparamref name="TService"/> currently 63 /// registered in the container. 64 /// </summary> 65 /// <typeparam name="TService"> Type of object requested. </typeparam> 66 /// <exception cref="ActivationException"> if there is are errors resolving 67 /// the service instance. </exception> 68 /// <returns> A sequence of instances of the requested <typeparamref name="TService"/> . </returns> 69 IEnumerable<TService> GetAllInstances<TService> (); 70 } 71 }
ServiceLocatorProvider
View Code
1 namespace Microsoft.Practices.ServiceLocation 2 { 3 /// <summary> 4 /// This delegate type is used to provide a method that will 5 /// return the current container. Used with the <see cref="ServiceLocator"/> 6 /// static accessor class. 7 /// </summary> 8 /// <returns> An <see cref="IServiceLocator"/> . </returns> 9 public delegate IServiceLocator ServiceLocatorProvider(); 10 }
ServiceLocator
View Code
1 namespace Microsoft.Practices.ServiceLocation 2 { 3 /// <summary> 4 /// This class provides the ambient container for this application. If your 5 /// framework defines such an ambient container, use ServiceLocator.Current 6 /// to get it. 7 /// </summary> 8 public static class ServiceLocator 9 { 10 private static ServiceLocatorProvider currentProvider; 11 12 /// <summary> 13 /// The current ambient container. 14 /// </summary> 15 public static IServiceLocator Current 16 { 17 get { return currentProvider(); } 18 } 19 20 /// <summary> 21 /// Set the delegate that is used to retrieve the current container. 22 /// </summary> 23 /// <param name="newProvider"> Delegate that, when called, will return 24 /// the current ambient container. </param> 25 public static void SetLocatorProvider(ServiceLocatorProvider newProvider) 26 { 27 currentProvider = newProvider; 28 } 29 } 30 }
动态单例模式的优点
支持多态。 运行时可变。 支持其它级别范围的单例,如:请求级、线程级和会话级等。 支持对象池。
纯CSS3实现手风琴风格菜单
今天分享一个如何使用纯 CSS3 创建手 风琴风格菜单 教程,菜单主要通过使用:target伪类来实现。
查看演示 下载源码
:target使用介绍
CSS3 target伪类是众多实用的CSS3特性中的一个。它用来匹配文档(页面)的URI中某个标志符的目标元素。具体来说,URI中的标志符通常会包含一 个”#”字符,然后后面带有一个标志符名称,比如#respond,target就是用来匹配ID为respond的元素的。
现在在页面中,点击一个ID链接后,页面只会跳转到相应的位置,但是并不会有比较明显的UI标识,使用:target伪类可以像:hover等伪类一样对目标元素定义样式。
第一步:HTML标签结构
一 个简单的无序列表,每个li中包含一个超链接和span,同时为每一个li添加一个不同的id和一个连接到这个id的超链接。为了添加样式和展开菜单项下 面的内容,需要使用:target伪类。
1 < ul class ="accordion" > 2 3 < li id ="one" class ="files" >< a href ="#one" > 我的文件 < span > 495 </ span ></ a ></ li > 4 5 < li id ="two" class ="mail" >< a href ="#two" > 邮件 < span > 26 </ span ></ a ></ li > 6 7 < li id ="three" class ="cloud" >< a href ="#three" > 网盘 < span > 58 </ span ></ a ></ li > 8 9 < li id ="four" class ="sign" >< a href ="#four" > 退出登录 </ a ></ li > 10 11 </ ul >
第二步:菜单布局基本样式
首先修改一些浏览器默认 样式,清除margin padding等等。
1 .accordion, 2 .accordion ul, 3 .accordion li, 4 .accordion a, 5 .accordion span { 6 margin : 0 ; 7 padding : 0 ; 8 border : none ; 9 outline : none ; 10 text-align : left ; 11 } 12 13 .accordion li { 14 list-style : none ; 15 }
定义菜单项链接样式,添加渐变,阴影的效果,定义字体等。这里没有指定固定的宽度,菜单的 宽度100%填充它的父元素,如果你想把菜单设置成300px,你可以给它添加一个父div,指定宽度为300px就可以了。虽然没有指定宽度,但是定义 了最小宽度,保证菜单布局能够正确的显示。
1 .accordion li > a { 2 display : block ; 3 position : relative ; 4 min-width : 110px ; 5 padding : 0 10px 0 40px ; 6 7 color : #fdfdfd ; 8 font : bold 14px/32px 黑体,宋体 ; 9 text-decoration : none ; 10 text-shadow : 0px 1px 0px rgba(0,0,0, .35) ; 11 12 background : #6c6e74 ; 13 background : -moz-linear-gradient(top, #6c6e74 0%, #4b4d51 100%) ; 14 background : -webkit-gradient(linear, left top, left bottom, color-stop(0%,#6c6e74), color-stop(100%,#4b4d51)) ; 15 background : -webkit-linear-gradient(top, #6c6e74 0%,#4b4d51 100%) ; 16 background : -o-linear-gradient(top, #6c6e74 0%,#4b4d51 100%) ; 17 background : -ms-linear-gradient(top, #6c6e74 0%,#4b4d51 100%) ; 18 background : linear-gradient(top, #6c6e74 0%,#4b4d51 100%) ; 19 20 -webkit-box-shadow : inset 0px 1px 0px 0px rgba(255,255,255, .1), 0px 1px 0px 0px rgba(0,0,0, .1) ; 21 -moz-box-shadow : inset 0px 1px 0px 0px rgba(255,255,255, .1), 0px 1px 0px 0px rgba(0,0,0, .1) ; 22 box-shadow : inset 0px 1px 0px 0px rgba(255,255,255, .1), 0px 1px 0px 0px rgba(0,0,0, .1) ; 23 }
定义数字指示器样式,当然如果你的菜单不需要数字指示器,你打可以删掉这个html结构中 span元素。
1 .accordion li > a span { 2 display : block ; 3 position : absolute ; 4 top : 7px ; 5 right : 0 ; 6 padding : 0 10px ; 7 margin-right : 10px ; 8 9 font : normal bold 12px/18px Arial, sans-serif ; 10 background : #404247 ; 11 12 -webkit-border-radius : 15px ; 13 -moz-border-radius : 15px ; 14 border-radius : 15px ; 15 16 -webkit-box-shadow : inset 1px 1px 1px rgba(0,0,0, .2), 1px 1px 1px rgba(255,255,255, .1) ; 17 -moz-box-shadow : inset 1px 1px 1px rgba(0,0,0, .2), 1px 1px 1px rgba(255,255,255, .1) ; 18 box-shadow : inset 1px 1px 1px rgba(0,0,0, .2), 1px 1px 1px rgba(255,255,255, .1) ; 19 }
第三步:添加图标样式
我们使用:before为菜单插入图标,图标的宽 高都是24px,用下面的样式使其正确的显示。我创建了一个sprite,包含了四个图标的正常和hover时候的不同样式。
1 .accordion > li > a:before { 2 position : absolute ; 3 top : 0 ; 4 left : 0 ; 5 content : '' ; 6 width : 24px ; 7 height : 24px ; 8 margin : 4px 8px ; 9 10 background-repeat : no-repeat ; 11 background-image : url(images/icons.png) ; 12 background-position : 0px 0px ; 13 } 14 15 .accordion li.files > a:before { background-position : 0px 0px ; } 16 .accordion li.files:hover > a:before, 17 .accordion li.files:target > a:before { background-position : 0px -24px ; } 18 19 .accordion li.mail > a:before { background-position : -24px 0px ; } 20 .accordion li.mail:hover > a:before, 21 .accordion li.mail:target > a:before { background-position : -24px -24px ; } 22 23 .accordion li.cloud > a:before { background-position : -48px 0px ; } 24 .accordion li.cloud:hover > a:before, 25 .accordion li.cloud:target > a:before { background-position : -48px -24px ; } 26 27 .accordion li.sign > a:before { background-position : -72px 0px ; } 28 .accordion li.sign:hover > a:before, 29 .accordion li.sign:target > a:before { background-position : -72px -24px ; }
第四步:子菜单HTML和样式
HTML:
同 样也使用ul作为子菜单,放到父菜单的li里面,如下代码:
1 < li id ="one" >< a href ="#one" > 我的文件 < span > 495 </ span ></ a > 2 < ul > 3 4 < li >< a href ="javascript:void(0);" >< em > 01 </ em > 音乐 < span > 42 </ span ></ a ></ li > 5 6 < li >< a href ="javascript:void(0);" >< em > 02 </ em > 视频 < span > 87 </ span ></ a ></ li > 7 8 < li >< a href ="javascript:void(0);" >< em > 03 </ em > 图片 < span > 366 </ span ></ a ></ li > 9 </ ul > 10 11 </ li >
CSS:
1 .sub-menu li a { 2 font : bold 12px/32px 黑体,宋体 ; 3 color : #797979 ; 4 text-shadow : 1px 1px 0px rgba(255,255,255, .2) ; 5 6 background : #e5e5e5 ; 7 border-bottom : 1px solid #c9c9c9 ; 8 9 -webkit-box-shadow : inset 0px 1px 0px 0px rgba(255,255,255, .1), 0px 1px 0px 0px rgba(0,0,0, .1) ; 10 -moz-box-shadow : inset 0px 1px 0px 0px rgba(255,255,255, .1), 0px 1px 0px 0px rgba(0,0,0, .1) ; 11 box-shadow : inset 0px 1px 0px 0px rgba(255,255,255, .1), 0px 1px 0px 0px rgba(0,0,0, .1) ; 12 } 13 14 .sub-menu li:last-child a { border : none ; } 15 16 .sub-menu li > a span { 17 color : #797979 ; 18 text-shadow : 1px 1px 0px rgba(255,255,255, .2) ; 19 background : transparent ; 20 border : 1px solid #c9c9c9 ; 21 22 -webkit-box-shadow : none ; 23 -moz-box-shadow : none ; 24 box-shadow : none ; 25 } 26 27 .sub-menu em { 28 position : absolute ; 29 top : 0 ; 30 left : 0 ; 31 margin-left : 14px ; 32 color : #a6a6a6 ; 33 font : normal 10px/32px Arial, sans-serif ; 34 }
第五步:定义鼠标悬浮和菜单激活时状态样式
当鼠标悬浮和菜单激活时改变 背景为绿色。
1 .accordion > li:hover > a, 2 .accordion > li:target > a { 3 color : #3e5706 ; 4 text-shadow : 1px 1px 1px rgba(255,255,255, .2) ; 5 background : #a5cd4e ; 6 background : -moz-linear-gradient(top, #a5cd4e 0%, #6b8f1a 100%) ; 7 background : -webkit-gradient(linear, left top, left bottom, color-stop(0%,#a5cd4e), color-stop(100%,#6b8f1a)) ; 8 background : -webkit-linear-gradient(top, #a5cd4e 0%,#6b8f1a 100%) ; 9 background : -o-linear-gradient(top, #a5cd4e 0%,#6b8f1a 100%) ; 10 background : -ms-linear-gradient(top, #a5cd4e 0%,#6b8f1a 100%) ; 11 background : linear-gradient(top, #a5cd4e 0%,#6b8f1a 100%) ; 12 } 13 14 .accordion > li:hover > a span, 15 .accordion > li:target > a span { 16 color : #fdfdfd ; 17 text-shadow : 0px 1px 0px rgba(0,0,0, .35) ; 18 background : #3e5706 ; 19 } 20 21 .sub-menu li:hover a { background : #efefef ; }
第六步:控制子菜单的显示与隐藏
为 了隐藏子菜单,我们需要定义子菜单的高度为0px。当点击父菜单时,为子菜单添加下滑显示的动态效果。为了实现下滑的效果,需要指定子菜单固定的高度。因 为这个教程中子菜单有三个link,所以这里指定了98px。如果你想加更多的子菜单就需要修改height为所有子菜单的高度和,当然如果你想要让它自 动变化,可以给高度赋值100%,但是这样下滑的动画效果就没有了。
1 .accordion li > .sub-menu { 2 height : 0 ; 3 overflow : hidden ; 4 5 -webkit-transition : all .2s ease-in-out ; 6 -moz-transition : all .2s ease-in-out ; 7 -o-transition : all .2s ease-in-out ; 8 -ms-transition : all .2s ease-in-out ; 9 transition : all .2s ease-in-out ; 10 } 11 12 .accordion li:target > .sub-menu { 13 height : 98px ; 14 }
总结:
到此纯CSS3实现的手风琴风格菜单就全部结束了。教程中我们主要通过使用伪类:before和:target来定义样式,使用:target来实现菜单点击展开子菜单事件。希望你能够喜欢这个教程。
分类: CSS3
作者: Leo_wl
出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息查看更多关于Microsoft.Practices.ServiceLocation 之 动态单例模式的详细内容...