三、服务解析(Resolving Services)
当你完成组件注册,并将组件暴露为适当的服务后你就可以通过容器或者容器的子生命周期域来解析服务(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>, |
枚举(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)的更多相关文章
- WebSocket安卓客户端实现详解(三)–服务端主动通知
WebSocket安卓客户端实现详解(三)–服务端主动通知 本篇依旧是接着上一篇继续扩展,还没看过之前博客的小伙伴,这里附上前几篇地址 WebSocket安卓客户端实现详解(一)–连接建立与重连 We ...
- iOS系统声音服务(System Sound Services)
系统声音服务(System Sound Services)提供了一个接口,用于播放不超过30秒的声音.它支持的文件格式有限,具体地说只有CAF.AIF和使用PCM或IMA/ADPCM数据的WAV文件. ...
- [转]访问 OData 服务 (WCF Data Services)
本文转自:http://msdn.microsoft.com/zh-SG/library/dd728283(v=vs.103) WCF 数据服务 支持开放式数据协议 (OData) 将数据作为包含可通 ...
- 网络安全服务(Network Security Services, NSS
网络安全服务(Network Security Services, NSS)是一套为网络安全服务而设计的库 支持支持安全的客户端和 服务器应用程序.使用NSS构建的应用程序可以支持SSL v2 和v3 ...
- JSON的三种解析方式
一.什么是JSON? JSON是一种取代XML的数据结构,和xml相比,它更小巧但描述能力却不差,由于它的小巧所以网络传输数据将减少更多流量从而加快速度. JSON就是一串字符串 只不过元素会使用特定 ...
- Android平台中实现对XML的三种解析方式
本文介绍在Android平台中实现对XML的三种解析方式. XML在各种开发中都广泛应用,Android也不例外.作为承载数据的一个重要角色,如何读写XML成为Android开发中一项重要的技能. 在 ...
- 【开源.NET】轻量级内容管理框架Grissom.CMS(第三篇解析配置文件和数据以转换成 sql)
该篇是 Grissom.CMS 框架系列文章的第三篇, 主要介绍框架用到的核心库 EasyJsonToSql, 把标准的配置文件和数据结构解析成可执行的 sql. 该框架能实现自动化增删改查得益于 E ...
- Qt中三种解析xml的方式
在下面的随笔中,我会根据xml的结构,给出Qt中解析这个xml的三种方式的代码.虽然,这个代码时通过调用Qt的函数实现的,但是,很多开源的C++解析xml的库,甚至很多其他语言解析xml的库,都和下面 ...
- 【Oracle学习笔记-3】关于Oracle 10g中各种服务解析
[原创]关于oracle 10g中各种服务解析 (2014/10/16 8:39:40) 时间:2014-10-16 8-58-30 作者:ssslinppp 1. 当首次安装oracle 1 ...
- python爬虫之数据的三种解析方式
一.正则解析 单字符: . : 除换行以外所有字符 [] :[aoe] [a-w] 匹配集合中任意一个字符 \d :数字 [0-9] \D : 非数字 \w :数字.字母.下划线.中文 \W : 非\ ...
随机推荐
- 你好,C++(18) 到底要不要买这个西瓜?4.1.6 操作符之间的优先顺序
4.1.6 操作符之间的优先顺序 在表达一些比较复杂的条件判断时,在同一个表达式中,有时可能会存在多个操作符.比如,我们在判断要不要买某个西瓜时,不仅要判断它的总价(单价8.2元/斤,一共10.3斤) ...
- jQuery实现图片预加载提高页面加载速度和用户体验
我们在做网站的时候经常会遇到这样的问题:一个页面有大量的图片导致页面加载速度缓慢,经常会出现一个白页用户体验很不好.那么如何解决这个问题呢?首先我们会想到的是提高服务器性能,使用静态缓存等手段来加快图 ...
- C 语言 联合union初见
1.什么是联合? “联合”是一种构造类型的数据结构.在一个“联合”内可以定义多种不同的数据类型, 一个被说明为该“联合”类型的变量中,允许装入该“联合”所定义的任何一种数据,这些数据共享同一段内存,已 ...
- 类和对象:拾遗 - 零基础入门学习Python039
类和对象:拾遗 让编程改变世界 Change the world by program 这节课谈的内容主要有: 组合 ...... 此处省略N多内容,具体请看视频讲解 ...... 类.类对象和实例对 ...
- QT creator中使用opencv
最近要用到opencv做图像方面的东西,网上很多是用VS加opencv,但自己对VS不怎么喜欢,想用QT Creator.在网上搜索了很多资料,终于花了一天的时间,在QT Creator上能使用ope ...
- IOS 使用新浪微博SDK
项目需要,测试了一下新浪微博SDK,现在记录一下初步使用过程. 1.下载导入新浪SDK. 2.去新浪开发者平台申请APPkey等. 3.工程中使用 4.在 APPDelegate中写两行 [Weibo ...
- cf E. Dima and Magic Guitar
http://codeforces.com/contest/366/problem/E |x1-x2|+|y1-y2|有四种情况 1.-(x1-x2)+(y1-y2); 2.(x1-x2)-(y1-y ...
- java集合经常出现空指针问题的解决方案
我自己问自己这个问题的时候都把自己给雷住了,但是现实如此,经常写的程序就是出现空指针的错误. 如: public List add(){ List list=null; try { list=new ...
- 奇葩的SQL*Net more data from client等待,导致批处理巨慢
<pre name="code" class="sql"><pre name="code" class="sql ...
- MVC4.0系统开发新手历程(二)
登录页 首先声明登录页不是我开发完成的 所以就简单的发下供大家参考 思路:由于是奖金系统,里面涉及到Money,所以在验证方面上下了很大的功夫,我看了下 主要的思想是 获取到那几个人会用到这个系统,然 ...