zoukankan      html  css  js  c++  java
  • IoC之AutoFac(二)——解析服务

    一 Resolve方法

    在您的组件注册了适当的服务后,您可以从内置的容器和子生命周期范围中解析服务。 您可以使用Resolve()方法,还是使用上篇的例子:

     1     private static IContainer Container { get; set; }
     2         static void Main(string[] args)
     3         {
     4             var builder = new ContainerBuilder();
     5             //注册服务
     6             builder.RegisterType<ConsoleOutput>().As<IOutput>();
     7             Container = builder.Build();
     8             //解析服务
     9             using (var scope=Container.BeginLifetimeScope())
    10             {
    11                var output= scope.Resolve<IOutput>();
    12                output.Write("outputsomething");
    13                Console.ReadKey();
    14             }  
    15         }

      解析服务时,Autofac将自动链接服务的整个依赖关系层次,并解析完全构建服务所需的任何依赖关系。 如果您的循环依赖关系被错误地处理,或者缺少必需的依赖关系,那么您将得到一个DependencyResolutionException。

    二 TryResolve和ResolveOptional方法

    如果您有可能注册或可能不被注册的服务,您可以使用ResolveOptional()或TryResolve()来尝试对服务进行有条件解决:

     1                 //解析服务
     2                 using (var scope = Container.BeginLifetimeScope())
     3                 {
     4                     //1.ResolveOptional:IOutput注册的话解析,未被注册返回null
     5                     var service = scope.ResolveOptional<IOutput>();
     6 
     7                     //2.TryResolve:IOutput注册的话解析获取一个类型实例,未注册返回null
     8                     IOutput output = null;
     9                     //如果有IOutPut服务,执行输出
    10                     if (scope.TryResolve<IOutput>(out output))
    11                     {
    12                         output.Write("outputsomething");
    13                     }
    14                     Console.ReadKey();
    15                 }

    三 解析服务时传参

      解析服务的时候,您可能会发现需要将参数传递给Autofac。 (如果您在注册时知道值,则可以在注册中提供它们,详细见上篇。)Resolve()方法使用可变长度的参数列表在注册时接受相同的参数类型

    3.1 可用参数类型

    Autofac提供了几种不同的参数匹配策略:

    • NamedParameter - 按名称匹配目标参数

    • TypedParameter - 按类型匹配目标参数(需要精确类型匹配)

    • ResolvedParameter - 灵活的参数匹配

    NamedParameter和TypedParameter只能提供常量值。

    ResolvedParameter可以用作提供从容器动态检索的值的方法,例如。 通过名称解析服务。

    3.2 带反射组件的参数

          当您解析基于反射的组件时,类型的构造函数可能需要您需要根据运行时值指定的参数,这在注册时不可用。 您可以在Resolve()方法调用中使用一个参数来提供该值。

      假设您有一个配置读取器,需要传递一个配置部分名称:

    1  public class ConfigReader : IConfigReader
    2     {
    3         public ConfigReader(string configSectionName)
    4         {
    5             // 存储配置的节点名称
    6         }
    7 
    8         // 读取基于节点名称的配置
    9     }

      您可以将参数传递给Resolve()调用,如下所示:

    //注册
     builder.RegisterType<ConfigReader>().As<IConfigReader>();
    //解析
     var reader = scope.Resolve<IConfigReader>(new NamedParameter("configSectionName", "mySectionName"));

      如果您有多个参数,只需通过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.3 具有Lambda表达式组件的参数

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

    在组件注册表达式中,您可以通过更改用于注册的代理签名来使用传入参数。 而不是仅仅使用IComponentContext参数,而是接收一个IComponentContext和一个IEnumerable <Parameter>:

    相关实例:

       // c 是当前组件上下文
       // p 是IEnumerable<Parameter>参数集合
       builder.Register((c, p) =>new ConfigReader(p.Named<string>("configSectionName")))
              .As<IConfigReader>();

    现在,当您解析IConfigReader时,您的lambda将使用传递的参数:

    //解析时传参
    var reader = scope.Resolve<IConfigReader>(new NamedParameter("configSectionName", "sectionName"));
  • 相关阅读:
    dfs模板
    24点
    个人阅读三
    个人阅读作业2:关于项目经历的心得
    代码复审
    Pair Project1:电梯控制程序
    第二次个人项目——阅读经典教材
    THE First Individual Project
    个人阅读作业3
    个人阅读作业2
  • 原文地址:https://www.cnblogs.com/wyy1234/p/9139005.html
Copyright © 2011-2022 走看看