当你完成组件注册,并将组件暴露为适当的服务后你就可以通过容器或者容器的子生命周期域来解析服务(After you have your components registered with appropriate services exposed, you can resolve services from the built container and child lifetime scopes)。你可以通过Resolve()方法来解析服务。

var builder = new ContainerBuilder();
builder.RegisterType<MyComponent>.As<IService>();
var container = builder.Build();
using(var scope = container.BeginLifetimeScope())
{
  var service = scope.Resolve<IService>();
}

  你可能已经注意到例子中是通过容器的子生命周期域对服务进行解析而不是直接使用容器(container)来接服务的——你也应该以这样的方式来解析服务。

  虽然也可以直接使用容器(container)来解析服务,但如果你这样做可能导致应用程序内存泄漏。所以建议你总是尽可能的在自生命周期域中解析服务,这样autofac能够帮助你妥善的处理对象销毁以及垃圾回收工作。你将在今后的章节中了解到更详细的内容。

  解析服务时,autofac将自动的连接服务的整个依赖层次,并且自动构件服务所需要的依赖项。当你的程序中存在循环依赖项或者依赖项缺失,那么程序将会抛出DependencyResolutionException异常。

  假设你有一个服务,但不能确定它是否已经注册到容器当中,你可以尝试使用ResolveOptional() 或者TryResolve()方法进行条件解析:

//如果已经注册了IService服务,那么它将被正确的解析,
//如果没有对IService服务进行注册,那么该方法将返回null
var service = scope.ResolveOptional<IService>(); //如果IProvider进行了注册,那么provider将获得对象,
//如果IProvider没有注册,那么你可以进行其他操作
IProvider provider = null
if(scope.TryResolve<IProvider>(out provider))
{
//服务被成功解析
}

3.1、为解析传递参数(Passing Parameters to Resolve)

  当你解析服务的时候,可能会需要额外的参数才能完成解析。(作为代替,如果在组件注册时就能明确该参数的值,你也可以直接在注册时提供该参数)。

  Resolve()方法用可变参数列表的方式接受参数。委托工厂(delegate factories)和Function<T>隐式关系类型(Function<T> implicit relationship type)也可以在解析时传递参数。(这段不是很明确,贴出原文等待高人指导:The Resolve() methods accept the same parameter types available at registration time using a variable-length argument list. Alternatively, delegate factories and the Func<T> implicit relationship type also allow ways to pass parameters during resolution.)

3.1.1、可用参数类型(Available Parameter Types)

  autofac提供了几种不同的参数匹配策略:

  • NamedParameter——通过参数名称进行匹配
  • TypedParameter——通过参数类型进行匹配
  • ResolvedParameter——灵活的参数匹配

  NamedParameter和TypedParameter只能够提供常量值

  ResolvedParameter提供的值可以从容器中动态的检索,比如通过名字来解析一个服务。(ResolvedParameter can be used as a way to supply values dynamically retrieved from the container, e.g. by resolving a service by name.)

3.1.2、参数与反射组件(Parameters with Reflection Components)

  使用基于反射进行创建的组件时,组件的构造函数可能会需要一个只有在运行时才能确定的值作为参数。你可向Resolve()方法传递一个parameter参数(个人理解这个parameter指代的是NamedParameter、TypedParameter、ResolveParameter)从而帮助容器创建该组件。

  如下的ConfigurationReader类,需要一个配置节(configuration section)名称作为参数:

public class ConfigReader : IConfigReader
{
public ConfigReader(string configurationSectionName)
{
//保存配置节名称
} //基于configurationSectionName读取配置
}

  你可以按下面的方式为Resolve()传递一个parameter参数

var reader = container.Resolve<ConfigReader>(new NamedParameter("configurationSectionName", "sectionName"));

  上面的例子中NamedParameter将按照名称(configurationSectionName)将值(sectionName)映射到ConfigReader的构造函数。

  如果你的组件有多个参数,同样可以使用Parameter参数传递给Resolve()方法:

var service = scope.Resolve<AnotherService>(
new NamedParameter("id", "service-identifier"),
new TypedParameter(typeof(Guid), Guid.NewGuid()),
new ResolvedParameter(
(pi, ctx) => pi.ParameterType == typeof(ILog) && pi.Name == "logger",
(pi, ctx) => LogManager.GetLogger("service")));

3.1.3、参数与Lambda表达式组件

  使用Lambda表达式注册的组件,在使用Resolve()方法传递parameter参数时需要在注册组件的Lambda表达式中增加一些额外的处理。

  在组件注册的表达式中,可以通过改变委托签名来使用传入的参数。之前使用的委托签名只有一个IComponentContext类型参数,而新的委托签名具有一个IComponentContext类型参数和一个IEnumerable<Parameter>类型的参数:

//注册是使用具有两个参数的委托
//c=IComponentContext,当前组件上下文,用于从容器中动态解析依赖
//p=IEnumerable<Parameter>,传入的参数集合
builder.Register((c, p) =>new ConfigReader(p.Named<string>("configSectionName"))).As<IConfigReader>();

  现在解析IConfigReader时,你的lambda表达是就能够使用传入的参数了:

IConfigReader reader = container.Resolve<IConfigReader>(new NamedParameter("configSectionName", "sectionName"));

3.1.4、非显示调用Resolve传参(Passing Parameters Without Explicitly Calling Resolve)

  autofac支持两种特性,允许自动生成服务工厂,该服务工厂可以在解析组件时使用强类型参数列表。

  • Delegate Factories允许你定义工厂委托方法
  • Func<T>隐式关心类型(Func<T> implicit relationship type)提供自动生成的工厂方法(The Func<T> implicit relationship type can provide an automatically-generated factory function.)

3.2、隐式关系类型(Implicit Relationship Types)

  autofac能够自动完成一些特定类型的解析工作,这些特定类型的组件和服务有着间接的关系,要使用这些关系,你只需要正常的注册你的组件,但是在调用Resolve()方法时,稍稍改变传入的参数或参数类型以此表明你要使用它们之间的间接关系。(这段话的意思我是理解了,但好难用中文来表述啊!我还是贴出原文吧。Autofac supports automatically resolving particular types implicitly to support special relationships between components and services. To take advantage of these relationships, simply register your components as normal, but change the constructor parameter in the consuming component or the type being resolved in the Resolve() call so it takes in the specified relationship type.要是看原文还不理解,也没关系,接着往下看一定会明白,而且会发现这段是作者在语言描述上卖了萌,哈哈)

  比如说,Autofac进行构造函数注入,而这个构造函数要求提供一个IEnumerable<ITask>类型的参数,autofac可能会找不到IEnumerable<ITask>匹配的组件,这种情况下它会去寻找所有ITask相对应的组件,并使用这些组件进行注入。(没看懂也别担心,下面还会有例子进行说明的)

3.2.1、支持的关系类型(Supported Relationship Types)

  下表总结了.net中,autofac支持的(隐式)关系类型,以下的每种类型都会有更详细的描述和用

关系 类型 含义

A需要B(A need B)

B 直接依赖(Direct Dependency)

将来的某一点A需要B(A need B at some point in the future)

Lazy<B> 延迟实例化(Delayed Instantiation)

A需要B直到将来某一点(A need B until some point int future)

Owned<B> 控制生命周期(Controlled Lifetime)

A需要创建B的实例(A need to create instances of B)

Func<B> 动态实例化(Dynamic Instantiation)

A为B提供类型为X和Y的参数(A provides paramteres of types X and Y to B)

Func<X,Y,B>

参数化的实例化(Parameterized Instantiation)

A需要所有B(A need all kinds of B)

IEnumerable<B>, IList<B>,
ICollection<B>

枚举(Enumeration)

A needs to know X about B

Meta<B> and Meta<B,X> Metadata Interrogation

A需要基于X对B进行选择

IIndex<X,B> Keyed Service Lookup

明天继续...

PS:本系列博客是对autofac英文资料的翻译,主要目的是为了提高自己英文阅读能力,同时能够帮助有需要的人,原文地址http://autofac.readthedocs.org/en/latest/getting-started/index.html。3.2节真心难翻译!

三、服务解析(Resolving Services)的更多相关文章

  1. WebSocket安卓客户端实现详解(三)–服务端主动通知

    WebSocket安卓客户端实现详解(三)–服务端主动通知 本篇依旧是接着上一篇继续扩展,还没看过之前博客的小伙伴,这里附上前几篇地址 WebSocket安卓客户端实现详解(一)–连接建立与重连 We ...

  2. iOS系统声音服务(System Sound Services)

    系统声音服务(System Sound Services)提供了一个接口,用于播放不超过30秒的声音.它支持的文件格式有限,具体地说只有CAF.AIF和使用PCM或IMA/ADPCM数据的WAV文件. ...

  3. [转]访问 OData 服务 (WCF Data Services)

    本文转自:http://msdn.microsoft.com/zh-SG/library/dd728283(v=vs.103) WCF 数据服务 支持开放式数据协议 (OData) 将数据作为包含可通 ...

  4. 网络安全服务(Network Security Services, NSS

    网络安全服务(Network Security Services, NSS)是一套为网络安全服务而设计的库 支持支持安全的客户端和 服务器应用程序.使用NSS构建的应用程序可以支持SSL v2 和v3 ...

  5. JSON的三种解析方式

    一.什么是JSON? JSON是一种取代XML的数据结构,和xml相比,它更小巧但描述能力却不差,由于它的小巧所以网络传输数据将减少更多流量从而加快速度. JSON就是一串字符串 只不过元素会使用特定 ...

  6. Android平台中实现对XML的三种解析方式

    本文介绍在Android平台中实现对XML的三种解析方式. XML在各种开发中都广泛应用,Android也不例外.作为承载数据的一个重要角色,如何读写XML成为Android开发中一项重要的技能. 在 ...

  7. 【开源.NET】轻量级内容管理框架Grissom.CMS(第三篇解析配置文件和数据以转换成 sql)

    该篇是 Grissom.CMS 框架系列文章的第三篇, 主要介绍框架用到的核心库 EasyJsonToSql, 把标准的配置文件和数据结构解析成可执行的 sql. 该框架能实现自动化增删改查得益于 E ...

  8. Qt中三种解析xml的方式

    在下面的随笔中,我会根据xml的结构,给出Qt中解析这个xml的三种方式的代码.虽然,这个代码时通过调用Qt的函数实现的,但是,很多开源的C++解析xml的库,甚至很多其他语言解析xml的库,都和下面 ...

  9. 【Oracle学习笔记-3】关于Oracle 10g中各种服务解析

    [原创]关于oracle 10g中各种服务解析 (2014/10/16 8:39:40) 时间:2014-10-16 8-58-30     作者:ssslinppp 1. 当首次安装oracle 1 ...

  10. python爬虫之数据的三种解析方式

    一.正则解析 单字符: . : 除换行以外所有字符 [] :[aoe] [a-w] 匹配集合中任意一个字符 \d :数字 [0-9] \D : 非数字 \w :数字.字母.下划线.中文 \W : 非\ ...

随机推荐

  1. 【转】char *str 和 char str[]的区别

    char str[] = "abcd";定义了一个局部字符数组,返回它的地址肯定是一个已经释放了的空间的地址. 此函数返回的是内部一个局部字符数组str的地址,且函数调用完毕后 此 ...

  2. ASP.NET环境下集成CKEditor与CKEditor实现文件上传

    1.从http://ckeditor.com网站上下载ckeditor_aspnet_3.6.4与ckfinder_aspnet_2.4; 2.解压下载的文件ckeditor_aspnet_3.6.4 ...

  3. javascript各种专业名词

    刚开始学javascript经常看到各种专业名词,在此整理一下个人的学习笔记: 直接量 直接量——就是程序中直接使用的数据值,如:88    //数字(String)"hello world ...

  4. Magento资源问题上CDN方案研究

    通过对Magento的了解,发现Magento的资源文件主要分布在media.js.skin三个文件夹里,media文件夹主要包括了系统自带编辑器WYSIWYG Editor 所有编辑器涉及到的资源( ...

  5. win7下的iis配置

    1.配置错误 说明:在处理向该请求提供服务所需的配置文件时出错.请检查下面的特定错误详细信息并适当地修改配置文件. 分析器错误消息:无法识别的属性“targetFramework”.请注意属性名称区分 ...

  6. 容器 vector :为何要有reserve

    关于STL容器,最令人称赞的特性之一就是是只要不超过它们的最大大小,它们就可以自动增长到足以容纳你放进去的数据.(要知道这个最大值,只要调用名叫max_size的成员函数.)对于vector和stri ...

  7. 程序设计C 实验三 题目九 方程式(0300)

    Description: Consider equations having the following form: a*x1*x1 + b*x2*x2 + c*x3*x3 + d*x4*x4 = 0 ...

  8. ucos_ii 上锁函数OSSchedLock()函数透析

    因为任务调度时一般都是通过OSTIMEDLY()来实现.在这个函数中会对当前的任务执行挂起.同时查看任务调度表中是否有优先级合适的就绪任务.如果当前任务运行时调用OSSchedLock()给调度器上锁 ...

  9. NET Core依赖注入解读&使用Autofac替代实现

    NET Core依赖注入解读&使用Autofac替代实现 标签: 依赖注入 Autofac ASPNETCore ASP.NET Core依赖注入解读&使用Autofac替代实现 1. ...

  10. mysql日志文件相关的配置【2】

    1.二进制日志是什么? mysql 的二进制日志用于记录数据库上做的变更. 2.二进制日志什么时间写到磁盘 1.总的来说二进制日志会在释放锁之前就写入磁盘.也就是说在commit完成之前:client ...