大多数IoC容器提供编程接口以及基于JSON/XML
文件的配置支持,Autofac
也不例外。
Autofac鼓励通过ContainerBuilder
类进行编程配置。使用编程接口是容器设计的核心。 如果在编译时无法选择或配置具体类,则建议使用JSON或XML。
在深入研究JSON/XML
配置之前,一定要阅读模块 - 这解释了如何处理比基本的JSON/XML
组件注册所允许的更复杂的场景。 JSON/XML
中的配置不是用于编程配置的功能特性替换,因此复杂的场景可能需要JSON/XML
和模块的组合。
Configuring With Microsoft Configuration (4.0+)
Quick Start
Default Assembly
Components
Modules
Type Names
Differences from Legacy Configuration
Additional Tips
Configuring With Application Configuration (Legacy Pre-4.0)
Setup
Components
Modules
Additional Config Files
Configuring the Container
Multiple Files or Sections
Quick Start
使用Microsoft配置进行配置(4.0+)
注意
Microsoft配置适用于Autofac.Configuration
的4.0+版本。它不适用于以前版本的配置包。
随着Microsoft.Extensions.Configuration
和Autofac.Configuration 4.0.0
的发布,Autofac
将受限于应用程序配置文件时,利用了以前不可用的更灵活的配置模型。如果您之前使用的是基于app.config
或web.config
的配置,则需要将配置迁移到新的格式,并更新用应用程序容器设置配置的方式。
快速开始
使用您的应用程序获取配置的基本步骤是:
在可由
Microsoft.Extensions.Configuration
读取的JSON或XML文件中设置您的配置。JSON配置使用
Microsoft.Extensions.Configuration.Json
XML配置使用
Microsoft.Extensions.Configuration.Xml
使用
Microsoft.Extensions.Configuration.ConfigurationBuilder
构建配置。创建一个新的
Autofac.Configuration.ConfigurationModule
并将构建的Microsoft.Extensions.Configuration.IConfiguration
传递给它。用你的容器注册
Autofac.Configuration.ConfigurationModule
。
一些简单注册的配置文件如下所示:
{
"defaultAssembly": "Autofac.Example.Calculator",
"components": [{
"type": "Autofac.Example.Calculator.Addition.Add, Autofac.Example.Calculator.Addition",
"services": [{
"type": "Autofac.Example.Calculator.Api.IOperation"
}],
"injectProperties": true
}, {
"type": "Autofac.Example.Calculator.Division.Divide, Autofac.Example.Calculator.Division",
"services": [{
"type": "Autofac.Example.Calculator.Api.IOperation"
}],
"parameters": {
"places": 4
}
}]
}
JSON更清晰,更易于阅读,但如果您更喜欢XML,则相同的配置如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<autofac defaultAssembly="Autofac.Example.Calculator">
<components name="0">
<type>Autofac.Example.Calculator.Addition.Add, Autofac.Example.Calculator.Addition</type>
<services name="0" type="Autofac.Example.Calculator.Api.IOperation" />
<injectProperties>true</injectProperties>
</components>
<components name="1">
<type>Autofac.Example.Calculator.Division.Divide, Autofac.Example.Calculator.Division</type>
<services name="0" type="Autofac.Example.Calculator.Api.IOperation" />
<injectProperties>true</injectProperties>
<parameters>
<places>4</places>
</parameters>
</components>
</autofac>
注意XML中组件和服务的序列“命名” - 这是由于Microsoft.Extensions.Configuration
处理序列集合(数组)的方式。
建立你的配置,并像下面这样用Autofac ContainerBuilder
进行注册:
//将配置添加到ConfigurationBuilder
var config = new ConfigurationBuilder();
//config.AddJsonFile来自Microsoft.Extensions.Configuration.Json
//config.AddXmlFile来自Microsoft.Extensions.Configuration.Xml
config.AddJsonFile("autofac.json");
//用Autofac注册ConfigurationModule
var module = new ConfigurationModule(config.Build());
var builder = new ContainerBuilder();
builder.RegisterModule(module);
默认程序集
您可以在配置中指定一个“默认程序集”选项来帮助以较短的方式写入类型。 如果您没有在类型或接口引用中指定程序集限定的类型名称,则将假定为默认程序集。
{
"defaultAssembly": "Autofac.Example.Calculator"
}
组件
组件是最常见的事情,你会注册。 您可以在每个组件上从生命周期范围指定参数。
组件被添加到配置中的顶级components
元素。里面是你想注册的组件的数组。
此示例显示了一个包含所有选项的组件,仅用于语法说明目的。您不会在每个组件注册中实际使用其中的每一个。
{
"components": [{
"type": "Autofac.Example.Calculator.Addition.Add, Autofac.Example.Calculator.Addition",
"services": [{
"type": "Autofac.Example.Calculator.Api.IOperation"
}, {
"type": "Autofac.Example.Calculator.Api.IAddOperation",
"key": "add"
}],
"autoActivate": true,
"injectProperties": true,
"instanceScope": "per-dependency",
"metadata": [{
"key": "answer",
"value": 42,
"type": "System.Int32, mscorlib"
}],
"ownership": "external",
"parameters": {
"places": 4
},
"properties": {
"DictionaryProp": {
"key": "value"
},
"ListProp": [1, 2, 3, 4, 5]
}
}]
}
Element Name | Description | Valid Values |
---|---|---|
type | The only required thing. The concrete class of the component (assembly-qualified if in an assembly other than the default). | Any .NET type name that can be created through reflection. |
services | An array of services exposed by the component. Each service must have a type and may optionally specify a key. | Any .NET type name that can be created through reflection. |
autoActivate | A Boolean indicating if the component should auto-activate. | true, false |
injectProperties | A Boolean indicating whether property (setter) injection for the component should be enabled. | true, false |
instanceScope | Instance scope for the component. | singleinstance, perlifetimescope, perdependency, perrequest |
metadata | An array of metadata values to associate with the component. Each item specifies the name, type, and value. | Any metadata values. |
ownership | Allows you to control whether the lifetime scope disposes the component or your code does. | lifetimescope, external |
parameters | A name/value dictionary where the name of each element is the name of a constructor parameter and the value is the value to inject. | Any parameter in the constructor of the component type. |
properties | A name/value dictionary where the name of each element is the name of a property and the value is the value to inject. | Any settable property on the component type. |
请注意,参数和属性都支持字典和可枚举值。您可以看到如何在上面的JSON结构中指定这些示例。
模块
与Autofac
一起使用模块时,可以在使用配置时将这些模块与组件一起注册。
模块被添加到配置中的顶级modules
元素。 里面是你想要注册的模块的数组。
这个例子显示了一个包含所有选项的模块,仅用于语法说明目的。 在每个模块注册中你不会使用每一个。
{
"modules": [{
"type": "Autofac.Example.Calculator.OperationModule, Autofac.Example.Calculator",
"parameters": {
"places": 4
},
"properties": {
"DictionaryProp": {
"key": "value"
},
"ListProp": [1, 2, 3, 4, 5]
}
}]
}
Element Name | Description | Valid Values |
---|---|---|
type | The only required thing. The concrete class of the module (assembly-qualified if in an assembly other than the default). | Any .NET type name that derives from Autofac.Module that can be created through reflection. |
parameters | A name/value dictionary where the name of each element is the name of a constructor parameter and the value is the value to inject. | Any parameter in the constructor of the module type. |
properties | A name/value dictionary where the name of each element is the name of a property and the value is the value to inject. | Any settable property on the module type. |
请注意,parameters
和properties
都支持字典和可枚举值。您可以看到如何在上面的JSON结构中指定这些示例。
如果您愿意,您可以使用不同的参数/属性
集多次注册相同的模块。
类型名称
在所有看到类型名称(组件类型,服务类型,模块类型)的情况下,都希望成为标准的程序集限定类型名称,您通常可以将其传递给Type.GetType(string typename)
。如果类型在defaultAssembly
中,则可以关闭程序集名称,但无论如何都不会伤害它。
程序集限定的类型名称具有包含名称空间,逗号和程序集名称的完整类型,如Autofac.Example.Calculator.OperationModule
,Autofac.Example.Calculator
。在这种情况下,Autofac.Example.Calculator.OperationModule
是类型,它在Autofac.Example.Calculator
程序集中。
泛型要复杂一点。配置不支持开放泛型,所以你也必须指定每个泛型参数的完全限定名。
例如,假设您在ConfigWithGenericsDemo
程序集中拥有一个存储库IRepository<T>
。我们还要说你有一个实现了IRepository<string>
的StringRepository
类。要在配置中注册,看起来像这样:
{
"components": [{
"type": "ConfigWithGenericsDemo.StringRepository, ConfigWithGenericsDemo",
"services": [{
"type": "ConfigWithGenericsDemo.IRepository`1[[System.String, mscorlib]], ConfigWithGenericsDemo"
}]
}]
}
如果你很难搞清楚你的类型名是什么,你可以在代码中这样做:
//将类型名称写入调试输出窗口,并将其复制/粘贴到您的配置中。
System.Diagnostics.Debug.WriteLine(typeof(IRepository<string>).AssemblyQualifiedName);
与传统配置的差异
从基于旧版(基于4.0版本)的基于app.config
的格式迁移到新格式时,需要注意以下一些重要更改:
没有
ConfigurationSettingsReader
。Microsoft.Extensions.Configuration
完全取代了旧的XML格式配置。旧版配置文档不适用于4.0+系列配置包。多个配置文件处理不同。旧配置有一个文件元素,可以自动将多个文件拉到一起进行配置。现在使用
Microsoft.Extensions.Configuration.ConfigurationBuilder
来完成此操作。- 支持
AutoActivate
。您可以指定组件现在自动激活,这是先前在配置中不可用的功能。 - XML使用元素子元素而不是属性。这有助于在使用
Microsoft.Extensions.Configuration
时保持XML和JSON解析相同,以便正确地组合XML和JSON配置源。 - 使用XML需要您使用数字命名组件和服务。
Microsoft.Extensions.Configuration
要求每个配置项都有一个名称和一个值。它支持顺序集合(数组)的方式是隐式地给集合名称中带有数字(“0”,“1”等等)的未命名元素。你可以在上面的快速入门中看到这个例子。如果您不使用JSON,则需要从Microsoft.Extensions.Configuration
中查看此需求,否则您将得不到您所期望的。 - 支持每个请求的生存期范围。以前,您无法将元素配置为具有每个请求的生存期范围。现在你可以。
- 名称/价值中的虚线消失了。
XML
元素的名称用于包含像注入属性这样的破折号 -
使用JSON配置格式,这些现在是驼峰式的,就像injectProperties
一样。 - 服务在一个子元素中被指定。传统配置允许在组件顶部正确声明服务。新系统要求服务集合中包含所有服务。
其他提示
新的Microsoft.Extensions.Configuration
机制增加了很多灵活性。你可能想要利用的东西:
- 环境变量支持。您可以使用
Microsoft.Extensions.Configuration.EnvironmentVariables
启用基于环境的配置更改。在不触摸代码的情况下调试,修补或修复某些内容的快速方法可能是根据环境切换Autofac
注册。 - 简单的配置合并。
ConfigurationBuilder
允许您从很多来源创建配置并将它们合并为一个。如果您有很多配置,请考虑扫描您的配置文件并动态构建配置,而不是硬编码路径。 - 自定义配置来源。您可以实现
Microsoft.Extensions.Configuration.ConfigurationProvider
自己支持的不仅仅是文件。如果要集中配置,请考虑数据库或REST API支持的配置源。
使用应用程序配置进行配置(传统4.0以前版本)
注意
如下所述的传统应用程序配置适用于Autofac.Configuration
的3.x和更早版本。它不适用于该软件包的4.0 +版本。
在发布Microsoft.Extensions.Configuration
和更新的配置模型之前,Autofac
绑定到标准的.NET应用程序配置文件中。 (app.config / web.config
)。在Autofac.Configuration
包的3.x系列中,这是配置东西的方法。
建立
使用传统的配置机制,你需要在你的配置文件的顶部附近的某处声明一个section处理程序:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration"/>
</configSections>
然后,提供描述您的组件的部分:
<autofac defaultAssembly="Autofac.Example.Calculator.Api">
<components>
<component
type="Autofac.Example.Calculator.Addition.Add, Autofac.Example.Calculator.Addition"
service="Autofac.Example.Calculator.Api.IOperation" />
<component
type="Autofac.Example.Calculator.Division.Divide, Autofac.Example.Calculator.Division"
service="Autofac.Example.Calculator.Api.IOperation" >
<parameters>
<parameter name="places" value="4" />
</parameters>
</component>
Components
defaultAssembly
属性是可选的,允许使用名称空间限定的而不是完全限定的类型名称。 这可以节省一些混乱和打字,特别是如果您使用每个程序集一个配置文件(请参阅下面的其他配置文件)。
组件
组件是最常见的事情,你会注册。 您可以在每个组件上从生命周期范围指定参数。
组件属性
以下可以用作component
元素的属性(默认值与编程API相同):
Attribute Name | Description | Valid Values |
---|---|---|
type | The only required attribute. The concrete class of the component (assembly-qualified if in an assembly other than the default.) | Any .NET type name that can be created through reflection. |
service | A service exposed by the component. For more than one service, use the nested services element. | As for type. |
instance-scope | Instance scope - see Instance Scope. | per-dependency, single-instance or per-lifetime-scope |
instance-ownership | Container’s ownership over the instances - see the InstanceOwnership enumeration. | lifetime-scope or external |
name | A string name for the component. | Any non-empty string value. |
inject-properties | Enable property (setter) injection for the component. | yes, no. |
组件子元素
Element | Description |
---|---|
services | A list of service elements, whose element content contains the names of types exposed as services by the component (see the service attribute.) |
parameters | A list of explicit constructor parameters to set on the instances (see example above.) |
properties | A list of explicit property values to set (syntax as for parameters.) |
metadata | A list of item nodes with name, value and type attributes. |
XML配置语法中缺少一些可通过编程API获得的功能,例如注册泛型。 在这些情况下建议使用模块。
模块
使用组件配置容器非常细致,可以快速得到详细的结果。 Autofac支持将组件打包到模块中,以便封装实现,同时提供灵活的配置。
模块按类型注册:
<modules>
<module type="MyModule" />
您可以使用与上述组件相同的方式将嵌套的参数和属性添加到模块注册中。
其他配置文件
您可以使用以下附加的配置文件:
<files>
<file name="Controllers.config" section="controllers" />
配置容器
首先,您必须从您的项目中引用Autofac.Configuration.dll
。
要配置容器,请使用ConfigurationSettingsReader
,并使用您给XML配置部分的名称进行初始化:
var builder = new ContainerBuilder();
builder.RegisterModule(new ConfigurationSettingsReader("mycomponents"));
//注册其他组件并调用Build()来创建容器。
容器设置阅读器将覆盖已经注册的默认组件; 您可以编写应用程序,使其以合理的默认值运行,然后仅覆盖特定部署所需的组件注册。
多个文件或部分
如果将文件名提供给ConfigurationSettingsReader
构造函数,则可以在同一个容器中使用多个设置读取器来读取不同的段或甚至不同的配置文件。