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 之 动态单例模式的详细内容...