您的位置:首页 > 其它

Microsoft.Practices.ServiceLocation 之 动态单例模式

2013-05-06 13:30 211 查看

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来实现菜单点击展开子菜单事件。希望你能够喜欢这个教程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: