zoukankan      html  css  js  c++  java
  • 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 }

     

    动态单例模式的优点

     

    1. 支持多态。
    2. 运行时可变。
    3. 支持其它级别范围的单例,如:请求级、线程级和会话级等。
    4. 支持对象池。

      纯CSS3实现手风琴风格菜单

      今天分享一个如何使用纯CSS3创建手风琴风格菜单教程,菜单主要通过使用:target伪类来实现。

      css3-accordion-main

      查看演示   下载源码

      :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

  • 相关阅读:
    开源 免费 java CMS
    运行shell脚本报错 &#39;357273277&#39;: command not found 解决的方法
    Android学习笔记之Spinner下拉列表使用案例
    HDU 1542 Atlantis (线段树 + 扫描线 + 离散化)
    DrawerLayout
    云计算设计模式(十三)——领导人选举模式
    算法之贪心思想
    [Android]Volley源代码分析(叁)Network
    oracle TABLE ACCESS BY INDEX ROWID 你不知道的索引回表-开发系列(三)
    JavaScript No Overloading 函数无重载之说
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3062646.html
Copyright © 2011-2022 走看看