zoukankan      html  css  js  c++  java
  • autoFac——茴字的三种写法

    autofac版本:3.5.2

    创建容器

    var builder = new ContainerBuilder();

    注册方式(这一部分的关注点在于给RegisterType、RegisterAssemblyTypes方法传递的参数,以及可以使用lambda表达式进行筛选

      1、泛型/类型注册,好处是很方便,但是缺点是:所注册的类型需要在当前项目中引用。使用了泛型注册,必须要类型明确。

    builder.RegisterType<MSDService>().As<IService>();

      2、使用反射+类名字符串进行注册。使用这种注册方式进行注册的类,是可以不需要进行引用的,但是类所在的程序集需要事先被加载进来。(动态加载的时候可以使用这种方式)

    builder.RegisterType(System.Type.GetType("MvcApplication1.Services.MSDService"));

      3、批量注册指定程序集中的所有非静态类。

    builder.RegisterAssemblyTypes(Assembly.Load("MSD.BLL"));

        3.1、通常我们并不需要注册一个程序集中所有的类。所以可以使用lambda表达式进行过滤。

             Assembly assembly = Assembly.GetExecutingAssembly();
             builder.RegisterAssemblyTypes(assembly).Where(x => x.Namespace.Equals("MvcApplication1.Services"));//注册指定命名空间下的所有类型。
             builder.RegisterAssemblyTypes(assembly).InNamespaceOf<MSDService>();//注册MSDService类型所在的命名空间下的所有类型。
             builder.RegisterAssemblyTypes(assembly).Except<MSDService>();//不注册MSDService类。
             builder.RegisterAssemblyTypes(assembly).InNamespace("MvcApplication1.Services");//注册在指定命名空间下的所有类。

      4、Lambda注册。1~3所使用的注册方式都是通过构造函数直接new出了对象。如果想在注册之时为类做更多的事情可以通过lambda表达式的注册方式进行注册。

    builder.Register(iComponentContext =>
                {
                    MSDService af = new MSDService();
                    if (af.Guid == null)
                        af.Guid = new System.Guid();//例子举的不好,但是大致的意思就是可以在注册之时,做其他的事情。
                    return af;
                });

      5、模块注册(这种注册方式最方便,在多人同时协作一个项目的时候,如果使用上面的方式,难免会产生代码冲突,使用这种就可以避免这种情况,只要各自实现IModule接口就可以了)。

    builder.RegisterAssemblyModules(assembly);//1、Module实现了IModule接口。2、RegisterAssemblyModules所注册的是实现了IModule接口的类。
    builder.RegisterAssemblyModules<MSDService>(assembly);//只注册assembly程序集中继承自MSDService的模块。

    解析已注册的类型

    IContainer container = builder.Build();
    IService msdService = container.Resolve<MSDService>();//如果事先没有对MSDService进行注册,那么Resolve时将会抛出异常。
    IService msdService1 = container.ResolveOptional<MSDService>();//如果事先没有对MSDService进行注册,那么将返回一个null值。
    IService msdService2 = null;
    if (container.TryResolve(out msdService2))//类似于tryParse
    {
       //如果解析成功
    }
    else
    {
      //如果解析失败
    }

    当一个类有多个构造函数的情况下,autofac会使用哪一个构造函数?

    使用尽可能最多参数的那个构造函数。详情:https://www.cnblogs.com/ancupofcoffee/p/5008469.html

    可以通过传入指定参数,从而来指定使用哪一种构造函数来生成我们需要的类型。

    var obj = container.Resolve<People>(new NamedParameter("guid", Guid.NewGuid()));

    NamedParameter     根据参数名称进行匹配。
    PositionalParameter      根据参数索引进行匹配,注意:起始索引为0。
    TypedParameter      根据类型进行匹配,注意:传入多个相同类型的TypedParameter,所有该类型的参数都将采用第一个TypedParameter的值。
    ResolvedParameter   接收两个Func参数,两个Func签名都接收两个相同的参数ParameterInfo和IComponmentContext,第一个参数为参数的信息,第二个参数还是当做IContainer使用就好了。第一个Func的返回值为bool,表明当前这个ResolvedParameter是否使用当前匹配到的参数,如果返回true,则会执行第二个Func;第二个Func返回一个object对象,用于填充构造参数值。

                container.Resolve<People>(new ResolvedParameter(
                 x =>
                 {
    
                 },
                 y =>
                 {
    
                 }
                ));

    注入方式(这部分要关注点是:结合Person和Eating的构造函数或属性,使用不同的方法进行注册,以及在注册时,可能会碰到的问题)

        public class Person
        {
            public Eating eat = null;
    
    
            //public Person(Eating eat)//如果加上这个构造函数,那么就是属性注入。去掉了,就是自动属性注入
            //{
            //    this.eat = eat;
            //}
    
            public string Name { get; set; }
    
    
            public void Eating()
            {
                eat.DoSth();
            }
        }
    Person.cs
        public class Eating
        {
            public void DoSth() {
    
            }
        }
    Eating.cs

    1、属性注入

    builder.RegisterType<Models.Eating>();
    builder.RegisterType<Models.Person>();
    var container1 = builder.Build();
    var person = container1.Resolve<Models.Person>();//在person类的构造函数里传入了Eating,但是并不需做其他的操作,只要在之此之前注册Eating就可以了。

    2、自动属性注入

    builder.RegisterType<Models.Eating>();
    builder.RegisterType<Models.Person>().PropertiesAutowired();//使用了PropertiesAutowired方法,只有在autofac中注册过的类型, 才能注入进去。
    var container2 = builder.Build();
    var person1 = container1.Resolve<Models.Person>();

    3、指定属性注入

    builder.RegisterType<Models.Person>().WithProperty(new Autofac.Core.NamedPropertyParameter("eat", new Models.Eating()));
    builder.RegisterType<Models.Person>().WithProperty("eat", new Models.Eating());

    4、lambda表达式注入

    builder.Register(iComponentContext =>
                {
                    Models.Person p = new Models.Person();
                    p.eat = new Models.Eating();//人为地注入了一个Eating
                    return p;
                });

    推荐使用不需要传参的构造注入和自动属性注入。不推荐使用方法注册。如果关联类型与注册类型没有继承/实现,那么builder.Build()会报错。

    5、当一个类与多个接口进行关联时

    builder.RegisterType<C1>().As<I1>().As<I2>().AsSelf();//不使用AsSelf(),如果想获取到一个I3接口的对象,就会抛异常。(只能获取到I1和I2)
    builder.RegisterType<C1>().AsImplementedInterfaces();
    一个接口或类型只能与一个类型进行关联,后面的关联会覆盖前面的关联。
    builder.RegisterType<C1>().As<I1>(); // class C1 : I1
    builder.RegisterType<C2>().As<I1>(); // class C2 : I1
    如果不想让后面的关联覆盖前面的关联,可以像下面这样做
    builder.RegisterType<C2>().As<I1>()PreserveExistingDefaults()//这样,C2就不会和I1进行关联了。

    可以使用Named <>、Meta<>方法,让一个接口和多个类型进行关联。

    最后,autoFac有5个生命周期函数(感觉跟vue或小程序中的差不多)

      1、OnRegistered

      2、OnPreparing

      3、OnActivating:OnActivating事件中推荐的三种操作:1.替换实例对象,或使用代理对象(通过ReplaceInstance方法);2.执行属性注入或方法注入;3.执行其他初始化任务。

      4、OnActived:OnActived事件中可以执行一些应用程序级别的任务。

      5、OnRelease

    builder.RegisterType<A>().OnActivating(e=>{调用一个方法去注册});
    var builder = new ContainerBuilder();
    builder.RegisterCallback(cr =>
                {
                    // 下面的Registered事件相当类型的OnRegistered事件
                    cr.Registered += (sender, eventArgs) =>
                    {
                        // OnPreparing事件
                        eventArgs.ComponentRegistration.Preparing += (o, preparingEventArgs) =>
                        {
    
                        };
                        // OnActivating事件
                        eventArgs.ComponentRegistration.Activating += (o, activatingEventArgs) =>
                        {
    
                        };
                        // OnActivated事件
                        eventArgs.ComponentRegistration.Activated += (o, activatedEventArgs) =>
                        {
    
                        };
                    };
                });
    // builder.RegisterType<...>...继续写其他的注册代码
    统一事件注册

    原文地址:https://www.cnblogs.com/ancupofcoffee/category/761892.html

  • 相关阅读:
    Asp.net2.0 中自定义过滤器对Response内容进行处理 dodo
    自动化测试工具 dodo
    TestDriven.NET 2.0——单元测试的好助手(转) dodo
    JS弹出窗口的运用与技巧 dodo
    ElasticSearch 简介 规格严格
    修改PostgreSQL字段长度导致cached plan must not change result type错误 规格严格
    Linux系统更改时区(转) 规格严格
    mvn编译“Cannot find matching toolchain definitions for the following toolchain types“报错解决方法 规格严格
    ElasticSearch 集群 & 数据备份 & 优化 规格严格
    Elasticsearch黑鸟教程22:索引模板的详细介绍 规格严格
  • 原文地址:https://www.cnblogs.com/vichin/p/13174546.html
Copyright © 2011-2022 走看看