当前位置: 首页 > news >正文

autofac文档:Component创建

AutoFac文档

目录

  1. 开始
  2. Registering components
  3. 控制范围和生命周期
  4. 用模块结构化Autofac
  5. xml配置
  6. 与.net集成
  7. 深入理解Autofac
  8. 指导
  9. 关于
  10. 词汇表

Registering components


ComponentCreation

http://code.google.com/p/autofac/wiki/ComponentCreation

autofac容器提供多个内置参数用来创造Component。

Component可以通过两种方式被创建:

  1. lambda表达式(通过反射)
  2. 提供一个现成的实例

ContainerBuilder 提供了 Register() 一类的方法去创建 Component。

ContainerBuilder使用 As 方法将Component封装成了服务使用。

 var builder = new ContainerBuilder();
builder.RegisterType<ConsoleLogger>().As<ILogger>();
builder.RegisterType<NHPersonRepository>().As<IFindPerson, IRepository<Person>>();
 

使用 As() 方法将Component的默认服务覆盖掉.所以

 container.Resolve<ILogger>();
 

上面的语法会成功.但是

 container.Resolve<ConsoleLogger>();
 

不会.

反射

AutoFac能够通过反射检查一个类型,选择一个合适的构造函数,创造这个对象的实例. RegisterType<T>() 和 RegisterType(Type) 两个方法以这种方式建立.

 builder.RegisterType<A>();  // Create A using reflection
builder.RegisterType(typeof(B)); // Non-generic version
 

选择构造函数和实例化依赖的过程会在后面的原理中讲述.

默认服务

通过反射创造的默认实例会是默认实现类型(A above will provide the service A)

表达式

发射对于component创建来说是个很不错的默认选择.事情变得乱七八糟尽管component创建逻辑建立在简单的构造函数上.

Autofac接受一个委托或者lambda表达式用来创建component.

 builder.Register(c => new A(c.Resolve<B>()));
 

表达式中的参数 c 是创建component的容器.使用这种方式而不是闭包()去访问容器非常重要.这确保了精确配置(DeterministicDisposal)和嵌套容器可以被正确支持.

使用这个参数可以满足额外的依赖,比如在这个例子中A需要B作为构造参数.

下面是一些用反射创建component的一些例子(很糟糕的需求)

复杂的参数

构造函数的参数不能使用简单的常量定义.与其困惑于如何在XML配置文件中构造一个特定类型的值,不如使用C#:

 builder.Register(c => new UserSession(DateTime.Now.AddMinutes(25)));
 

(当然session的终结是你很有可能想在xml配置文件中制定的)

属性注入

这是推荐的属性初始化方式. IComponentContext.ResolveOptional() 很方便:

 builder.Register(c => new A(){ MyB = c.ResolveOptional<B>() });
 

或者, PropertiesAutowired() 这个方法也可以导致属性注入.

 builder.RegisterType<X>().PropertiesAutowired();
 

不管怎样,在大多数情况下不推荐使用属性注入.替代的选择像 Null Object -使用构造函数注入重载构造函数或者构造函数参数默认值来创造一个干净的,"不变的"components.

根据参数来选择实现方法

使用IOC容器创建对象的最大好处之一就是一个类型可以被实例化成不同的实例,这通常体现在运行阶段,而不是配置阶段.

 builder.Register<CreditCard>((c, p) => {
    var accountId = p.Named<string>("accountId");
    if (accountId.StartsWith("9"))
    return new GoldCard(accountId);
    else
    return new StandardCard(accountId);
});
 

在这个例子中,信用卡被是实例化成两个类:金卡和普通卡.这是由运行时段提供的卡ID决定的.

在这个例子中,一个可选的参数P被提供给构造函数.

可以像下面这样使用这种注册方法来获得实例:

 var card = container.Resolve<CreditCard>(new NamedParameter("accountId", "12345"));
 

当使用委托工厂或者使用一个委托来创建CreditCard的实例时,可以使语言清晰,而且是强类型的.

Default Service

使用这种表达式创建的component默认值是由表达式推导出来的.

提供的实例(Provided Instances)

有时候我们需要将autofac集成到一个系统中.在很多情况下,我们需要在容器中使用一些已经在系统存在的单例对象的实例.这时就不能创造一个单例的component(因为这些对象已经在系统中存在了),而是应该在容器中将它们注册为实例:

 builder.RegisterInstance(MySingleton.Instance).ExternallyOwned();
 

这种方法会确保系统中的单例实例最终转化为由容器托管的单例实例.

Default Service

默认值就是注册的那个实例

开放的泛型类型

autofac支持开放的泛型类型.使用 RegisterGeneric() 这个方法:

 builder.RegisterGeneric(typeof(NHibernateRepository<>))
    .As(typeof(IRepository<>))
    .InstancePerLifetimeScope();
 

当从容器中请求一个匹配的类型时,autofac会自动匹配一个等价的具体实现类型.

 // Autofac will return an NHibernateRepository<Task>
var tasks = container.Resolve<IRepository<Task>>();
 

注册一个具体的类型((e.g. IRepository<Person> )会覆盖掉上面的泛型注册.

默认的注册

如果一个类型被多次注册,以最后注册的为准.

为避免各种情况,可以使用 PreserveExistingDefaults() 修饰符

 builder.Register<X1>().As<IX>();
builder.Register<X2>().As<IX>().PreserveExistingDefaults();
 

在这种情况下,X1会是IX的默认值.(如果不适用 PreserveExistingDefaults() 修饰符,X2会是默认值,因为它是最后被注册的)

转载于:https://www.cnblogs.com/wolegequ/archive/2012/06/02/2531945.html

相关文章:

  • 详解阿里云企业办公解决方案,开启办公“轻”时代
  • 分享45个android实例源码,很好很强大.收藏吧!!!
  • 小试R空间处理新库sf
  • Gnuplot 使用技巧
  • js去除空格12种方法
  • 与、或、异或、取反、左移和右移
  • oracle数据库设置了默认字段,但默认值无效
  • MFC应用程序向导生成的最简单程序HelloMFC详解
  • miniconda管理python[windows10]
  • eclipse中字体太小
  • C# Math函数 字符串、整数装换
  • 存储与虚拟机主机管理(五)
  • 短文本合并重复(去重)的简单有效做法
  • css布局,左右固定中间自适应实现
  • 写给兔小白的js教程(4)
  • [rust! #004] [译] Rust 的内置 Traits, 使用场景, 方式, 和原因
  • 4. 路由到控制器 - Laravel从零开始教程
  • JS+CSS实现数字滚动
  • JS创建对象模式及其对象原型链探究(一):Object模式
  • leetcode388. Longest Absolute File Path
  • react 代码优化(一) ——事件处理
  • Webpack 4x 之路 ( 四 )
  • 力扣(LeetCode)56
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 使用权重正则化较少模型过拟合
  • 手写双向链表LinkedList的几个常用功能
  • 为视图添加丝滑的水波纹
  • 优化 Vue 项目编译文件大小
  • 7行Python代码的人脸识别
  • Semaphore
  • 关于Android全面屏虚拟导航栏的适配总结
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • ​3ds Max插件CG MAGIC图形板块为您提升线条效率!
  • ​低代码平台的核心价值与优势
  • !!Dom4j 学习笔记
  • # 学号 2017-2018-20172309 《程序设计与数据结构》实验三报告
  • $jQuery 重写Alert样式方法
  • (3)llvm ir转换过程
  • (6)添加vue-cookie
  • (LeetCode) T14. Longest Common Prefix
  • (MATLAB)第五章-矩阵运算
  • (二)什么是Vite——Vite 和 Webpack 区别(冷启动)
  • (二十三)Flask之高频面试点
  • (南京观海微电子)——I3C协议介绍
  • (区间dp) (经典例题) 石子合并
  • (未解决)macOS matplotlib 中文是方框
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • ****Linux下Mysql的安装和配置
  • .locked1、locked勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET / MSBuild 扩展编译时什么时候用 BeforeTargets / AfterTargets 什么时候用 DependsOnTargets?
  • .NET Entity FrameWork 总结 ,在项目中用处个人感觉不大。适合初级用用,不涉及到与数据库通信。
  • .net 发送邮件
  • .Net8 Blazor 尝鲜