AutoFac 依赖注入之XML/JSON配置文件

 AutoFac提供编程接口以及基于XML/JSON文件的配置支持,实现IOC。

Autofac鼓励通过ContainerBuilder类进行编程配置。使用编程接口是容器设计的核心。 如果在编译时无法选择或配置具体类,则建议使用JSON或XML。

一.使用Microsoft配置进行配置(4.0+)

Microsoft配置适用于Autofac.Configuration的4.0+版本。它不适用于以前版本的配置包。

随着Microsoft.Extensions.Configuration和Autofac.Configuration 4.0.0的发布,Autofac将受限于应用程序配置文件时,利用了以前不可用的更灵活的配置模型。如果您之前使用的是基于app.config或web.config的配置,则需要将配置迁移到新的格式,并更新用应用程序容器设置配置的方式。

快速开始

使用您的应用程序获取配置的基本步骤是:
1.在可由Microsoft.Extensions.Configuration读取的JSON或XML文件中设置您的配置。
2.JSON配置使用Microsoft.Extensions.Configuration.Json
3.XML配置使用Microsoft.Extensions.Configuration.Xml
4.使用Microsoft.Extensions.Configuration.ConfigurationBuilder构建配置。
5.创建一个新的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.

请注意,parametersproperties都支持字典和可枚举值。您可以看到如何在上面的JSON结构中指定这些示例。

如果您愿意,您可以使用不同的参数/属性集多次注册相同的模块。

类型名称

在所有看到类型名称(组件类型,服务类型,模块类型)的情况下,都希望成为标准的程序集限定类型名称,您通常可以将其传递给Type.GetType(string typename)。如果类型在defaultAssembly中,则可以关闭程序集名称,但无论如何都不会伤害它。

程序集限定的类型名称具有包含名称空间,逗号和程序集名称的完整类型,如Autofac.Example.Calculator.OperationModuleAutofac.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);




猜你喜欢

转载自blog.csdn.net/gaozhigang/article/details/80667139