图片 2

        [Fact]
        public void GetInstanceWithName()
        {
            ILogger instance = locator.GetInstance<ILogger>(“AdvancedLogger”);
            Assert.IsType(typeof(AdvancedLogger), instance);
        }

例子

/// <summary>
/// Logger customized for MEF
/// </summary>
[Export(typeof(ILogger))]
public class MefLogger : ILogger
{
    /// <summary>
    /// Writes the log.
    /// </summary>
    /// <param name=”message”>The message.</param>
    public void WriteLog(string message)
    {
        Console.WriteLine(“String built from MEF: {0}.”, message);
    }
}

/// <summary>
/// Gets or sets the writer.
/// </summary>
/// <value>The writer.</value>
[Import]
public ILogger Writer { get; set; }
public void Run()
{
    // first we build the catalog
    var catalog = new AssemblyCatalog(Assembly.GetExecutingAssemb
    //create the container using the catalog
    var container = new CompositionContainer(catalog);
    container.ComposeParts(this);
    //use the resolved property
    Writer.WriteLog(“Mef message”);
}

        [Fact]
        public void GetlAllInstance_ForUnknownType_ReturnEmptyEnumerable()
        {
            IEnumerable<IDictionary> instances = locator.GetAllInstances<IDictionary>();
            IList<IDictionary> list = new List<IDictionary>(instances);
            Assert.Equal(0, list.Count);
        }

这几个工具的站点

Microsoft Unity  http://unity.codeplex.com

Service Locator http://commonservicelocator.codeplex.com

MEF  .net4.0内含,3.x前在codeplex上开源

Unity Application Block (Unity)是一个轻量级的, 可扩展的依赖注入容器.
它有助于构建松耦合的应用程序和为开发者提供以下便利:

例子

/// <summary>
/// Utility to configure the container
/// </summary>
public sealed class UnityContainerConfigurator
{
    /// <summary>
    /// Configures this instance.
    /// </summary>
    /// <returns></returns>
    public static IUnityContainer Configure()
    {
        var container = new UnityContainer()
        .RegisterType<ILogger, FileLogger>()
        .RegisterType<Writer>();
        return container;
    }
}

// create a new instance of Microsoft Unity container
  var provider = new
UnityServiceLocator(UnityContainerConfigurator.Configure());
  // assign the container to the Service Locator provider

xUnit.net:下一代单元测试框架?
http://www.infoq.com/cn/news/2007/09/xunit-net

MEF

The main reasons to use MEF are if:

Ø You need to implement external and reusable extensions in your client
application, but you might have different implementations in different
hosts .

Ø You need to auto-discover the available extensions at runtime .

Ø You need a more powerful and extensible framework than a normal
Dependency Injection framework, and you want to get rid of the various
boot-strapper and initializer objects .

Ø You need to implement extensibility and/or modularity in your
components .

If your application doesn’t require any of the items in these lists, you
probably should not implement the IoC pattern, and you might not need to
use Unity and MEF .

图片 1

Common Service Locator官方与下载
http://www.codeplex.com/CommonServiceLocator

例子

[InjectionConstructor]
public Writer(ILogger logger)
{
    this.logger = logger;
}

//Prepare the container 
var container = new UnityContainer(); 
//We specify that the logger to be used is the FileLogger 
container.RegisterType<ILogger, FileLogger>(); 
//and how to instantiate a new Writer 
container.RegisterType<Writer>(); 
//Here Unity knows how to create the new constructor 
var writer = container.Resolve<Writer>(); 
writer.Write(“Some Text.”);

通过UnityContainer实现注入

        [Fact]
        public void GetAllInstances()
        {
            IEnumerable<ILogger> instances = locator.GetAllInstances<ILogger>();
            IList<ILogger> list = new List<ILogger>(instances);
            Assert.Equal(2, list.Count);
        }

  ServiceLocator.SetLocatorProvider(() => provider);

  // resolve objects using the service locator
  var writer = ServiceLocator.Current.GetInstance<Writer>();
  writer.Write(“Some Text.”);

ServiceLocator的实现非常简单,而且代码也很少

namespace UnityAdapter.Tests
{
    /// <summary>
    /// ServiceLocatorTestWithConfig
    /// </summary>
    /// <remarks>author PetterLiu http://wintersun.cnblogs.com </remarks>
    public class ServiceLocatorTestWithConfig
    {
        protected readonly IServiceLocator locator;

Utility

The main reasons to use Unity (or any other IoC container) are if:

Ø You have dependencies between your objects .

Ø You need to manage the lifetime of an object .

Ø You want to manage dependencies at runtime, such as cache,
constructors, and properties .

Ø You need to intercept the creation of an object .

Unity is a lightweight, extensible dependency injection container that
supports interception, constructor injection, property injection, and
method call injection. You can use Unity in a variety of different ways
to help decouple the components of your applications, to maximize
coherence in components, and to simplify design, implementation,
testing, and administration of these applications.

Unity is a general-purpose container for use in any type of Microsoft®
.NET Framework-based application. It provides all of the features
commonly found in dependency injection mechanisms, including methods to
register type mappings and object instances, resolve objects, manage
object lifetimes, and inject dependent objects into the parameters of
constructors and methods and as the value of properties of objects it
resolves.

        protected IServiceLocator CreateServiceLocator()
        {
            IUnityContainer container = new UnityContainer();
            UnityConfigurationSection section =
                (UnityConfigurationSection)ConfigurationManager.GetSection(“unity”);
            section.Containers.Default.Configure(container);                
            return new UnityServiceLocator(container);
        }

简单比较

Service Locator:
最简单的实现形式,对于比较简单的应用合适,本身的实现代码也很简单

Utility:复杂度中等,介于Service Locator和MEF之间

MEF:以一个完整的框架形式展现, .net 4内置支持,提供生命期等各种管理

实例代码:
http://cid-56b433ad3d1871e3.office.live.com/self.aspx/.Public/Ioc%5E_Di.rar

接下来先来看一上适配器的代码:

Service Locator

  • 简化对象的创建,特别在分层对象结构和依赖的情形下
  • 它支持需求的抽象化,这允许开发人员在运行时或在配置文件中指定依赖,简化横切关注点(crosscutting
    concerns)的管理
  • 它通过把组件配置推给容器来决定,增加了灵活性 
  • 服务定位能力; 这使客户端能够存储或缓存容器

图片 2

        [Fact]
        public void GetDefaultInstance()
        {
            ILogger instance = locator.GetInstance<ILogger>();
            Assert.IsType(typeof(SimpleLogger), instance);
        }

        [Fact]
        public void GenericOverload_GetAllInstances()
        {
            List<ILogger> genericLoggers = new List<ILogger>(locator.GetAllInstances<ILogger>());
            List<object> plainLoggers = new List<object>(locator.GetAllInstances(typeof(ILogger)));
            Assert.Equal(genericLoggers.Count, plainLoggers.Count);
            for (int i = 0; i < genericLoggers.Count; i++)
            {
                Assert.Equal(
                    genericLoggers[i].GetType(),
                    plainLoggers[i].GetType());
            }
        }
    }
}

图片 3图片 4config
<?xml version=”1.0″ encoding=”utf-8″ ?>
<configuration>
    <configSections>
        <section name=”unity”   
              type=”Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration, Version=1.1.0.0,    
            Culture=neutral, PublicKeyToken=31bf3856ad364e35″ />
    </configSections>
    <unity>
        <typeAliases>
            <!– Lifetime manager types –>
            <typeAlias alias=”singleton”   
              type=”Microsoft.Practices.Unity.ContainerControlledLifetimeManager,    
          Microsoft.Practices.Unity” />
        </typeAliases>
        <containers>
            <container>
                <types>
                    <!– Lifetime managers specified using the type aliases –>
                    <type type= “UnityAdapter.Tests.Components.ILogger, UnityAdapter.Tests”   
                        mapTo=”UnityAdapter.Tests.Components.SimpleLogger, UnityAdapter.Tests”>
                        <lifetime type=”singleton” />
                    </type>
                    <type type= “UnityAdapter.Tests.Components.ILogger, UnityAdapter.Tests”   name=”SimpleLogger”  
                        mapTo=”UnityAdapter.Tests.Components.SimpleLogger, UnityAdapter.Tests”>
                        <lifetime type=”singleton” />
                    </type>
                    <type type= “UnityAdapter.Tests.Components.ILogger, UnityAdapter.Tests”  name=”AdvancedLogger”  
                        mapTo=”UnityAdapter.Tests.Components.AdvancedLogger, UnityAdapter.Tests”>
                        <lifetime type=”singleton” />
                    </type>    
                </types>
            </container>
        </containers>
    </unity>
</configuration>

测试的接口,实现类参看UnityAdapter.Tests项目,接下来看下用配制文件的程序代码:

配制文件:

        public ServiceLocatorTestWithConfig()
        {
            locator = CreateServiceLocator();
        }

        [Fact]
        public void GetInstanceWithName2()
        {
            ILogger instance = locator.GetInstance<ILogger>(“SimpleLogger”);
            Assert.IsType(typeof(SimpleLogger), instance);
        }

xUnit介绍
NUnit的创造者Jim
Newkirk
公布了一个新的单元测试框架,叫做xUnit.net。这个以NUnit接班人自许的新框架打算消除NUnit的错误和缺点,并打算在框架中加入一些最佳实践和扩展能力。

xUnit.net 项目官方
http://www.codeplex.com/xunit/

相关引用:
Unity介绍

using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Configuration;
using Microsoft.Practices.ServiceLocation;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using Microsoft.Practices.Unity.ServiceLocatorAdapter;
using UnityAdapter.Tests.Components;
using Xunit;

Common Service Locator介绍

图片 5图片 6UnityServiceLocator
 1  public class UnityServiceLocator : ServiceLocatorImplBase
 2     {
 3         private IUnityContainer container;
 4 
 5         public UnityServiceLocator(IUnityContainer container)
 6         {
 7             this.container = container;
 8         }
 9 
10         /// <summary>
11         ///             When implemented by inheriting classes, this method will do the actual work of resolving
12         ///             the requested service instance.
13         /// </summary>
14         /// <param name=”serviceType”>Type of instance requested.</param>
15         /// <param name=”key”>Name of registered service you want. May be null.</param>
16         /// <returns>
17         /// The requested service instance.
18         /// </returns>
19         protected override object DoGetInstance(Type serviceType, string key)
20         {
21             return container.Resolve(serviceType, key);        
22         }
23 
24         /// <summary>
25         ///             When implemented by inheriting classes, this method will do the actual work of
26         ///             resolving all the requested service instances.
27         /// </summary>
28         /// <param name=”serviceType”>Type of service requested.</param>
29         /// <returns>
30         /// Sequence of service instance objects.
31         /// </returns>
32         protected override IEnumerable<object> DoGetAllInstances(Type serviceType)
33         {
34             return container.ResolveAll(serviceType);
35         }
36     }

Common Service Locator 类库包含应用程序和框架开发者引用Service
location共享的接口。这个类库提供了在IOC容器和Service
locators之上抽象。使用这个类库允许一个应用程序在没有强引用依赖下间接的访问的能力。期望用这个类库,第三方应用程序和框架开始利用IOC/Service
location改变在没有绑定他们到一个具体的实现。
  
这个项目包括所有验证过locator功能需求的具体实现测试套件。另外,在未来日子里项目中将包含几个流行IOC容器适配器程序。

admin

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注