zoukankan      html  css  js  c++  java
  • Autofac官方文档翻译--二、解析服务--1解析参数传递

    Autofac 传递解析参数

    注册组件公开相应的服务之后,你可以从container构造器和子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>();
    }
    复制代码
      你会发现在这个例子中,从一个lifetime scope 中解析服务,而不是直接在容器中解析,你也应该这样做。
      然而也有可能从根容器中解析组件,在你的应用中这样做在一些情况下可能导致内存泄露。推荐你总是从一个lifetime scope中解析组件,以尽可能确保服务实例妥善处理和垃圾回收。在本节中你可以阅读到很多关于控制范围和生命周期的知识。
      当解析服务时,Autofac 将自动链接服务的整个依赖层次结构,并且解析全面构建服务所需的任何依赖关系。如果你有循环依赖关系处理不当或缺失必须的依赖,你会得到一个DependencyResolutionException。
      如果你有一个服务,不知道是否被注册了,你可以尝试使用ResolveOptional()或TryResolve()来解决:
    复制代码
    // 如果 IService 被注册, 它将被解析;  
    // 如果没有被注册,将返回null;
    var service = scope.ResolveOptional<IService>();
    
    // 如果 IProvider 被注册,  provider 变量将获取此值,
    // 否则,你可以进行其他操作 
    //
    IProvider provider = null;
    if(scope.TryResolve<IProvider>(out provider))
    {
      // Do something with the resolved provider value.
    }
    复制代码
    ResolveOptional()和TryResolve()围绕一个被注册的特定服务的条件本质。如果服务被注册,将尝试解析,如果解析失败,你将得到一个DependencyResolutionExceptionResolve()异常。如果你需要对一个服务进行条件判断,此条件建立在此服务是否能被成功解析,用一个try/catch块包裹Resolve()之后调用。

    1、传递解析参数

    当解析服务时,你会发现需要为解析传入参数。
    Resolve()方法使用可变长度的参数列表,匹配注册时相同的参数类型。另外,委托工厂和Func<T>隐式关系类型也允许在解析期间传递参数。

    1.1可用参数类型

    Autofac 提供不同的参数匹配策略:
    • NamedParameter - 通过名称匹配目标参数
    • TypedParameter - 通过类型匹配目标参数
    • ResolvedParameter - 灵活的参数匹配
    NamedParameter 和TypedParameter 只能提供固定值。
    ResolvedParameter 可为一个从容器提供动态检索值,例如通过一个名称解析服务。

    1.2反射组件参数

    有当你解析基于反射的组件时,该类型的构造函数可能需要你在运行时指定一个参数值,不适合在注册时指定该值。你需要使用一个参数在Resolve()方法调用时提供这个值。
    例如,你有一个配置读取类 ,需要传入一个配置节的名称:
    复制代码
    public class ConfigReader : IConfigReader
    {
      public ConfigReader(string configSectionName)
      {
        // Store config section name
      }
    
      // ...read configuration based on the section name.
    }
    复制代码
    你可以像这样,在解析时传递一个参数:
    var reader = scope.Resolve<ConfigReader>(new NamedParameter("configSectionName", "sectionName"));
    作为注册时参数,NamedParameter在案例中将映射到与命名相匹配的构造函数参数上。
    如果你有多个参数,只需要把他们全部传递到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")));

    1.3Lambda表达式组件参数

    使用lambda表达式组件注册,你需要在你的lambda表达式中添加参数处理,所以当调用Resolve()传递它们时,你可以利用它们。

    在组件注册表达式中,你可以通过改变注册时使用的委托签名,来传递参数。而不是仅仅使用一个IComponentContext 参数,一个IComponentContext 和一个 IEnumerable<Parameter>:

    // 注册委托使用两个参数:
    // c = The current IComponentContext to dynamically resolve dependencies
    // p = An IEnumerable<Parameter> with the incoming parameter set
    builder.Register((c, p) =>
                     new ConfigReader(p.Named<string>("configSectionName")))
           .As<IConfigReader>();

    现在,当你解析IConfigReader时,你的lambda表达式使用此参数来传递:

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

    1.4传递参数不调用Resolve

    全Autofac 支持两种特性,允许你自动生成服务工厂,在解析时使用强类型参数列表。对于创建需要参数的组件实例,这是非常清洁的方式。

    引用: https://www.cnblogs.com/chiyueqi/p/autofac_ResolveParameters.html

  • 相关阅读:
    java-多个数的和
    大道至简第二章
    大道至简第一章感悟上
    Tools
    LruCache
    Fragment
    科普指纹识别
    Python使用MySQL数据库
    Eclipse中添加PyDev插件
    UniversalAndroidImageLoader出现异常:ImageLoader: Unable to resolve host "https": No address associated with host
  • 原文地址:https://www.cnblogs.com/nimorl/p/12626418.html
Copyright © 2011-2022 走看看