• 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

  • 相关阅读:
    An intriguing failing of convolutional neural networks and the CoordConv solution
    Arbitrary Style Transfer in Real-time with Adaptive Instance Normalization
    Win10下用Anaconda安装TensorFlow
    批处理框架
    智能分单算法
    海量数据处理利器greenplum——初识
    使用R画地图数据
    跟我一起ggplot2(1)
    一文搞懂HMM(隐马尔可夫模型)
    借助亚马逊S3和RapidMiner将机器学习应用到文本挖掘
  • 原文地址:https://www.cnblogs.com/vichin/p/13174546.html
Copyright © 2020-2023  润新知