Common Service Locator介绍
Common Service Locator 类库包含应用程序和框架开发者引用Service location共享的接口。这个类库提供了在IOC容器和Service locators之上抽象。使用这个类库允许一个应用程序在没有强引用依赖下间接的访问的能力。期望用这个类库,第三方应用程序和框架开始利用IOC/Service location改变在没有绑定他们到一个具体的实现。
这个项目包括所有验证过locator功能需求的具体实现测试套件。另外,在未来日子里项目中将包含几个流行IOC容器适配器程序。
Common Service Locator官方与下载
http://www.codeplex.com/CommonServiceLocator
接下来先来看一上适配器的代码:
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 }
测试的接口,实现类参看 UnityAdapter.Tests项目,接下来看下用配制文件的程序代码:
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;
namespace UnityAdapter.Tests
{
/// <summary>
/// ServiceLocatorTestWithConfig
/// </summary>
/// <remarks> author PetterLiu http://wintersun.cnblogs.com </remarks>
public class ServiceLocatorTestWithConfig
{
protected readonly IServiceLocator locator;
public ServiceLocatorTestWithConfig()
{
locator = CreateServiceLocator();
}
protected IServiceLocator CreateServiceLocator()
{
IUnityContainer container = new UnityContainer();
UnityConfigurationSection section =
(UnityConfigurationSection)ConfigurationManager.GetSection( " unity " );
section.Containers.Default.Configure(container);
return new UnityServiceLocator(container);
}
[Fact]
public void GetInstanceWithName()
{
ILogger instance = locator.GetInstance < ILogger > ( " AdvancedLogger " );
Assert.IsType( typeof (AdvancedLogger), instance);
}
[Fact]
public void GetDefaultInstance()
{
ILogger instance = locator.GetInstance < ILogger > ();
Assert.IsType( typeof (SimpleLogger), instance);
}
[Fact]
public void GetInstanceWithName2()
{
ILogger instance = locator.GetInstance < ILogger > ( " SimpleLogger " );
Assert.IsType( typeof (SimpleLogger), instance);
}
[Fact]
public void GetAllInstances()
{
IEnumerable < ILogger > instances = locator.GetAllInstances < ILogger > ();
IList < ILogger > list = new List < ILogger > (instances);
Assert.Equal( 2 , list.Count);
}
[Fact]
public void GetlAllInstance_ForUnknownType_ReturnEmptyEnumerable()
{
IEnumerable < IDictionary > instances = locator.GetAllInstances < IDictionary > ();
IList < IDictionary > list = new List < IDictionary > (instances);
Assert.Equal( 0 , list.Count);
}
[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());
}
}
}
}
配制文件:
<?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>
相关引用:
Unity介绍
Unity Application Block (Unity)是一个轻量级的, 可扩展的依赖注入容器. 它有助于构建松耦合的应用程序和为开发者提供以下便利:
- 简化对象的创建,特别在分层对象结构和依赖的情形下
- 它支持需求的抽象化,这允许开发人员在运行时或在配置文件中指定依赖,简化横切关注点(crosscutting concerns)的管理
- 它通过把组件配置推给容器来决定,增加了灵活性
- 服务定位能力; 这使客户端能够存储或缓存容器
xUnit介绍
NUnit的创造者Jim Newkirk公布了一个新的单元测试框架,叫做xUnit.net。这个以NUnit接班人自许的新框架打算消除NUnit的错误和缺点,并打算在框架中加入一些最佳实践和扩展能力。
xUnit.net:下一代单元测试框架?
http://www.infoq.com/cn/news/2007/09/xunit-net
xUnit.net 项目官方
http://www.codeplex.com/xunit/