威尼斯人线上娱乐

反射壹4分钟速成,程序集扫描

7 5月 , 2019  

经进度序集扫描, 能够活动注册符合规则的类型. 那种办法, 很方便.
那1篇就介绍下程序集扫描吧. 

Autofac,autofac普通话文书档案

通进程序集扫描, 能够自动注册符合规则的类型. 那种艺术, 很方便.
那一篇就介绍下程序集扫描吧. 

一、扫描

实质上后面早已介绍过, 那种形式. 可是并不全.

先看1个此前的不二等秘书籍:

var builder = new ContainerBuilder();

builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly());//.Where(n => n.Name.EndsWith("son"));

var container = builder.Build();

var person = container.Resolve<Person>();
person.Self();

var dog = container.Resolve<Dog>();
dog.Say();

威尼斯人线上娱乐 1

 

二、过滤

设若小编并不想注册那么多的品类, 但是又想透进度序集的登记格局去登记,
那怎么办呢?

  1. Where过滤

    builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).Where(n => n.Name.EndsWith(“son”));

    var container = builder.Build();

    var person = container.Resolve();
    person.Self();

 威尼斯人线上娱乐 2

只必要在末端加多Where方法去过滤就可以. 在过滤之后, var dog =
container.Resolve<Dog>()那句话就回报错, 因为他并未注册进去.

2. Except过滤

builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).Except<Person>();

var container = builder.Build();
//报错
//var person = container.Resolve<Person>();
//person.Self();

var dog = container.Resolve<Dog>();
dog.Say();

威尼斯人线上娱乐 3

 使用Except的时候, 有二个留意的末节项. 

builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).Except<Person>(c => c.As<IPerson>());
var container = builder.Build();

var person = container.Resolve<IPerson>();
person.Self();
//报错
//var personA = container.Resolve<Person>();
//personA.Self();

威尼斯人线上娱乐 4

从地点能够看来, 尽管Person无法直接用了, 可是却足以因而IPerson的章程,
来获取Person的实例.

 

3、钦赐服务

挂号的时候, 有三个As方法, 在事先已经观看过了, 便是未有表明过.
其实就是钦定服务. 然而在先后集扫描里面, 就不是As()了

builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces();
var container = builder.Build();

var person = container.Resolve<IPerson>();
person.Self();

威尼斯人线上娱乐 5

额, 这里仍然调用了四个构造函数, 别在意, 笔者用的是上1篇的代码. 

 在AsImplementedInterfaces()方法中, 就注册了装有符合规则的服务.

 

通进度序集扫描,
能够自行注册符合规则的类型. 那种办法, 很方便.
那一篇就介绍下程序集扫描吧. 一、扫描 其实前…

    • 概述
      什么是反光

一、扫描

Reflection,汉译为反射。
       
那是.Net中得到运转时类型音信的章程,.Net的应用程序由多少个部分:‘程序集(Assembly)’、‘模块(Module)’、‘类型(class)’组成,而反射提供一种编制程序的不二等秘书诀,让程序猿能够在先后运转期获得那多少个组成都部队分的相干新闻,举个例子:

实际前边早已介绍过, 那种格局. 可是并不全.

       
Assembly类能够拿走正在运行的装配件音讯,也足以动态的加载装配件,以及在装配件中搜寻类型音讯,并创制该类型的实例。
Type类能够获取对象的类型新闻,此新闻包罗对象的全体因素:方法、构造器、属性等等,通过Type类能够拿走这么些因素的新闻,并且调用之。
MethodInfo包括方法的音讯,通过那一个类能够赢得方法的名号、参数、重返值等,并且能够调用之。
那样,还有FieldInfo、伊芙ntInfo等等,这么些类都包蕴在System.Reflection命名空间下。

先看三个事先的主意:

 

var builder = new ContainerBuilder();

builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly());//.Where(n => n.Name.EndsWith("son"));

var container = builder.Build();

var person = container.Resolve<Person>();
person.Self();

var dog = container.Resolve<Dog>();
dog.Say();
类型 作用
Assembly 通过此类可以加载操纵一个程序集,并获取程序集内部信息
EventInfo 该类保存给定的事件信息
FieldInfo 该类保存给定的字段信息
MethodInfo 该类保存给定的方法信息
MemberInfo 该类是一个基类,它定义了EventInfo、FieldInfo、MethodInfo、PropertyInfo的多个公用行为
Module 该类可以使你能访问多个程序集中的给定模块
ParameterInfo 该类保存给定的参数信息      
PropertyInfo 该类保存给定的属性信息

威尼斯人线上娱乐 6

 

 

 

二、过滤

 

若是本身并不想注册那么多的门类, 然而又想经进度序集的挂号情势去挂号,
这怎么做呢?

那个都是废话,我们1并看多少个案列就完全学会了,在此证实下,反射用到的一些基础技术有
运维运算符,type
类,这里就只是多的演讲了,如有不会得以去园子里面自个儿去找,本身也写过1篇有关文章,轻巧的牵线了运维运算符。

  1. Where过滤

    builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).Where(n => n.Name.EndsWith(“son”));

    var container = builder.Build();

    var person = container.Resolve();
    person.Self();

 

 威尼斯人线上娱乐 7

  • 怎么获得1个类的目的

只要求在背后加多Where方法去过滤就能够. 在过滤之后, var dog =
container.Resolve<Dog>()那句话就回报错, 因为她并不曾注册进去.

幸存工程文件(项目文件)结构如下

2. Except过滤

威尼斯人线上娱乐 8

builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).Except<Person>();

var container = builder.Build();
//报错
//var person = container.Resolve<Person>();
//person.Self();

var dog = container.Resolve<Dog>();
dog.Say();

People类代码如下:

威尼斯人线上娱乐 9

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Entity
{
    public class People
    {

        public People()
        {
            Console.WriteLine("People被创建了");
        }
        public People(String Name)
        {
            this.Name = Name;
            Console.WriteLine("People被创建了,并且people的名字是"+this.Name);
        }
        public string Name { get; set; }//自动属性,在程序实例化的过程中会自动创建私有的字段,这个字段在people 内存中开辟控件存储其值(本文称为公有属性)在此感谢ENC博主的支持和评论,
        public int Age { get; set; }

        public string Sex { get; set; }

        public string msg;//公有字段

        private string qq;//私有字段
        private string address;//私有属性
        public string Address { get => Address; set => Address = value; }
        public override string ToString()
        {
            return "{" + $"name:{this.Name},age:{this.Age},sex{this.Sex}" + "}";
        }
        public string Say()
        {
            return "hello! " + this.Name;
        }
    }
}

 使用Except的时候, 有多少个只顾的细枝末节项. 

 

builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).Except<Person>(c => c.As<IPerson>());
var container = builder.Build();

var person = container.Resolve<IPerson>();
person.Self();
//报错
//var personA = container.Resolve<Person>();
//personA.Self();

 debug 目录如下:

威尼斯人线上娱乐 10

威尼斯人线上娱乐 11

从上边能够看来, 即便Person不能够一直用了, 不过却足以通过IPerson的法子,
来获取Person的实例.

 

 

 

三、钦命服务

 这里表达下,程序中,并未引用 Entity
类库,也绝非引用Entity..DLL文件,请自行引用,我们只要不实例化获得3个目的啊??平日的时候,大家都以透过new
得到一个对象,如:

注册的时候, 有贰个As方法, 在头里早已观望过了, 正是未有解释过.
其实便是内定服务. 可是在先后集扫描里面, 就不是As()了

using Entity;
using System;
using System.Collections.Generic;
using System.Data;

namespace testData
{
    class Program
    {
        static void Main(string[] args)
        {
            People p = new People();
            Console.WriteLine(p);
            People peop = new People("张三");
            Console.WriteLine(p);
            Console.Read();
        }
    }
}
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces();
var container = builder.Build();

var person = container.Resolve<IPerson>();
person.Self();

威尼斯人线上娱乐 12

威尼斯人线上娱乐 13

大家再来看下类的花色是什么样?

额, 这里仍然调用了七个构造函数, 别在意, 笔者用的是上1篇的代码. 

 

 在AsImplementedInterfaces()方法中, 就登记了有着符合规则的服务.

using Entity;
using System;
using System.Collections.Generic;
using System.Data;

namespace testData
{
    class Program
    {
        static void Main(string[] args)
        {
            Type t = typeof(People);
            Console.WriteLine(t);
            Type type= Type.GetType("People");
            Console.WriteLine(type);//这里是得不到的,因为配件装载只能在程序集内部使用
            Console.Read();
        }
    }
}

 

笔者们来学学下,怎么着依照类类型举办反射。

  • 类的反光

    对象无参构造函数反射

 

 static void Main(string[] args)
        {
            Type type = typeof(People);
            People people= Activator.CreateInstance(type) as People;//实例化得带一个类
            Console.WriteLine(people);
            Console.Read();
        }

 

    对象有构造函数参反射

 static void Main(string[] args)
        {
            Type type = typeof(People);
            People people= Activator.CreateInstance(type) as People;//实例化得到一个类
            Console.WriteLine(people);
            //实例化得到一个类,该类有一个参数
            People p = Activator.CreateInstance(type, new object[] { "Wbcsky" }) as People;
            Console.WriteLine(p);
            Console.Read();
        }

 威尼斯人线上娱乐 14

    对象泛型反射

 static void Main(string[] args)
        {
            Type type = typeof(People);
            People p1 = Activator.CreateInstance<People>();
            Console.WriteLine(p1);
            Console.Read();
        }

关于指标的反光,就只有那两种样式,分别是泛型反射,泛型反射有且只好获得无参数的实例对象,和一般无参反射像相比,反射反射收缩了装箱拆箱的操作。有参数反射大家是依照参数的相继,传递的object
数组。这一个反射都以基于 Activator.CreateInstance 来实现的。

 

质量字段的反射

– 获取五个对象的全体属性

 

   static void Main(string[] args)
        {
            Type type = typeof(People);
            System.Reflection.PropertyInfo[] p = type.GetProperties();
            foreach (var item in p)
            {
                Console.WriteLine("属性名:" + item.Name + "属性类型" + item.PropertyType.FullName + "属性类型命名空间" + item.PropertyType.Namespace);
            }
            Console.Read();
        }

大家都通晓,在C#中,属性的封装有二种,一种全写,1种简写,全写的在少数工具书中称之为私有属性,简写的在工具书上称为公有属性。

如: 

   public int Age { get; set; }
我们称为简写,工具书上叫做公有属性。
则:

      private string address;//私有属性
        public string Address { get => Address; set => Address = value; }
或

private string iD;
public string ID

{
get { return this.iD; }
set { this.iD = value; }
}

这种写法我们称为私有属性,私有属性中,当使用=>这种运算的,我们称为lambda表达式写法,使用this 关键字的写法,我们称为面向对象写法。不论哪一种属性,我们都叫做属性,我们在反射中获取属性使用的是Type 类的 .GetProperties()方法来获取类的全部属性。我们来看下执行结果。

这里就不过多的介绍获取属性的值了,我们在下面介绍获取属性的值。

– 获取钦点名称的质量和值及设置三个值

  static void Main(string[] args)
        {
            Type type = typeof(People);
            System.Reflection.PropertyInfo Property = type.GetProperty("Name");//注意属性名称字符串大小写
            if (Property == null) Console.Read();//如果属性名称大小写错误或者不存在,我们Property对象将会是null
            Console.WriteLine("属性名:" + Property.Name + "属性类型" + Property.PropertyType.FullName + "属性类型命名空间" + Property.PropertyType.Namespace);
            //获取属性的值
            People p= Activator.CreateInstance(type) as People;//获取对象
            object oName = Property.GetValue(p); //获取值
            Console.WriteLine("旧" + oName);
            Property.SetValue(p, "abc");//设置一个值
            oName = Property.GetValue(p); //获取值
            Console.WriteLine("新" + oName);
            Console.Read();
        }

看了地点的代码,大家会意识,获取属性使用的是Type类的 GetProperty方法来完毕的。获取值和装置值,使用的是 PropertyInfo
 类的 GetValue和Set value 来产生的。实施结果如下

因为伊始化的时候是空,所以旧就如何也从未出口。有人会说了,这几个未有赢获得类,进行点写的便利,为何要如此写吗,告诉你一句话,存在就是有道理的,这里能够回顾的告知,大家繁多时候,二个效应更新过于频仍,我们完全能够把那个类写入配置文件中,去安顿那么些类对象的效应接纳。掌握就能够,不驾驭清背下来代码。

– 获取对象的之所以公有字段和村办字段

 在这里表明下,多数少人都不亮堂字段和个性的分别,小编这里差不多说下,理解就可以,不知晓不影响学习,大家一个类的变量实行包装,会现身get
,set
设置那么些字段的访问权限,那几个包裹大家称为属性,而那么些变量大家誉为字段,字段不钦赐修饰符的时候暗中同意为个人的。

   static void Main(string[] args)
        {
            Type type = typeof(People);
            System.Reflection.FieldInfo[] fi = type.GetFields();
            Console.WriteLine("\r\n-------------------- 获取对象的所以公有字段-------------------------------\r\n");
            foreach (System.Reflection.FieldInfo item in fi)
            {
                Console.WriteLine("公有字段名" + item.Name);
            }
            Console.WriteLine("\r\n-------------------- 获取对象的所有私有字段-------------------------------\r\n");
            System.Reflection.FieldInfo[] fiprivate = type.GetFields(System.Reflection.BindingFlags.Instance |
                System.Reflection.BindingFlags.NonPublic);

            foreach (System.Reflection.FieldInfo item in fiprivate)
            {
                Console.WriteLine("私有字段名" + item.Name);
            }
            Console.Read();
        }

威尼斯人线上娱乐 15

那是一个难处,可是在实质上开拓进度中很少使用,不过那我们不能够不要会,不然中期写组件开垦等文书档案,该看不懂了,希图好瓜子,我们初始听传说了。

看了上边的代码,及字段及性能的牵线,大家会意识,输出的结果,共有的很好理解,大家类里面定义的变量
钦定public 现在,我们就足以由此

GetFields ()
方法返回我们想要的公有字段数组,我们输出了名字,这里就不过多的解释了。 
反射私有字段,输出的这个是什么啊,乱码七招的。

私有字段名<Name>k__BackingField
私有字段名<Age>k__BackingField
私有字段名<Sex>k__BackingField
私有字段名qq
私有字段名address

 其实很好理解,我们在前面说过获取所有属性的时候说过属性分为私有和公有,其中私有属性有两种写法,其实私有属性是对私有变量的封装,也可以说是对私有字段的封装,公有属性是什么呢?
其实公有属性在编译过程中, 为了方便JTL 公共语言运行环境更好的编译,自动生成了一个私有的字段,这个字段是根据操作系统不同生成不同前缀的私有字段,这里生成的是K_前缀的。这样我们就好理解为什么上图会多输出三个字段。
如果此处还不理解,那么请看其他博客吧本文介绍的毕竟都是基础。而实际开发过程中反射这基本使用的都是组件。
  • 获得钦点的公有字段

**在此地就不介绍获取钦赐公有字段的值了,和质量获取是如出1辙的。

**

 static void Main(string[] args)
        {
            Type type = typeof(People);
            Console.WriteLine("\r\n-------------------- 获取对象的指定公有字段-------------------------------\r\n");
            Console.WriteLine("字段名" + type.GetField("msg").Name);
            Console.Read();
        }

 

代码很轻松,唯有一行。那么有人会问,这字段分为个人和共有的,为什么未有介绍获取个人属性的吗???为何未有介绍获取钦赐个人字段的呢???,其实答案很简短,你看过有封装属性的时候有个体的啊,私有的是或不是都说在类的在那之中使用,那本身反射类就足以了,小编外部也不应用。那私有字段呢,为什么未有,不是不曾,是有不过基本不选择,因为共有属性会默许生成私有字段,那一个私有字段的前缀分化,所以不能得到,没意义。所以基本没人使用。

 

反射壹4分钟速成,程序集扫描。措施和构造函数的反光

 获取公有方法并调用

  Type type = typeof(People);
            Console.WriteLine("\r\n-------------------- 获取对象的共有方法并且调用-------------------------------\r\n");
            System.Reflection.MethodInfo mi = type.GetMethod("Say");
            People p= Activator.CreateInstance<People>();
            p.Name = "张四伙";//为了省事,这里不使用属性反射添加值了
            object oReturn = mi.Invoke(p, null);//第一个参数为反射的对象,第二个参数object 数组,为参数,参数按顺序填写
            Console.WriteLine(oReturn);
            Console.Read();

 

 这么些未有何样解释的了,前面最难的性格字段反射,大家都会了,那些就不是主题材料了,自身多看看代码?

获得当前类下的持有够着函数

static void Main(string[] args)
{
Type type = typeof(People);
///获取所有的一般不会使用,这里就不过多介绍了
System.Reflection.ConstructorInfo[] info = type.GetConstructors();//获取当前类下所有够着函数
foreach (System.Reflection.ConstructorInfo item in info)
{
Console.WriteLine("是否为虚方法"+item.IsVirtual);
Console.WriteLine("名称"+item.Name);
}

Console.WriteLine("\r\n-------------------- 获取当前类下参数类型匹配的够着函数-------------------------------\r\n");
System.Reflection.ConstructorInfo con = type.GetConstructor(new Type[] { typeof(string) });
object o = con.Invoke(new object[] { "zhangsan" });
People peo = o as People;
Console.WriteLine(peo);
Console.Read();
}

 

世家会说了,够着函数不正是类对象的实例化吗?,大家后面不是讲过反射类对象了吗,为何这些里面还要获得实例化对象呢?

骨子里某个时候,大家在选取抽象类和接口的时候,大家通过事先学习的类的反射是千篇1律能够成功获得类的对象,这里之说以那样疏解,因为有局地反光项目在优化的时候,会采取在这之中查找条件,即从够着函数起初得带类的对象,功效会更加高级中学一年级些。

大家在开拓进度中,尽量有内而外,尽量把总结如故评释得到程序代码推行进度中的最终去做,那样使用内部存款和储蓄器会少,成效会更加高。

下边大家上学那篇小说的第二大基本。程序集反射

 

程序集反射

 

何以是先后集反射呢,参与大家三层架构,作者不想引用bll层和model
层,也不想引用他们的dll,就能够在职业层得带她的靶子引用,那些怎么达成呢???大家一道来上学下吧!

威尼斯人线上娱乐 16

率先程序集中删除Entity.dll 程序编写翻译跟目录放置 ectity.dll文件。看下列代码

 

using System;
using System.Collections.Generic;
using System.Data;

namespace testData
{
    class Program
    {
        static void Main(string[] args)
        {
            /*装载程序集*/
            System.Reflection.Assembly assembly = System.Reflection.Assembly.Load("Entity");
            // System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom("Entity.bll");//使用这种方式需要写扩展名
            Console.WriteLine("\r\n-------------------- 程序集反射1-------------------------------\r\n");
            Type peopleType = assembly.GetType("Entity.People");//得到people 类的type 类型
            object obj = Activator.CreateInstance(peopleType);
            System.Reflection.MethodInfo me = peopleType.GetMethod("Say");
            object ret = me.Invoke(obj, null);
            Console.WriteLine(ret);
            Console.WriteLine("\r\n-------------------- 程序集反射2-------------------------------\r\n");
            object PeopleObj = assembly.CreateInstance("Entity.People");//直接得到类的实例化对象
            Console.WriteLine(PeopleObj);
            Console.Read();
        }
    }
}

 威尼斯人线上娱乐 17威尼斯人线上娱乐 18

 

代码注释已经很显明了,这里就只是多的表达了,大家来看下实施结果 。

威尼斯人线上娱乐 19

 

——————– 程序集反射一——————————-

People被创制了
hello!

——————– 程序集反射二——————————-

People被创设了
{name:,age:0,sex}

 

在先后集反射中,大家就未有章程在.属性 .字段
.方法的调用了,那年,大家只可以通过质量,方法的反射区域地质调查用了,这里演示的不多,就三种常用的案列,本文只是介绍了成本进程中常用的案列。

 

总计及扩张

 壹.反光一般是用在体系化不能成功的气象下,比如接口再次回到看xml,而那个xml
常常改动,并不曾二个钦命的法则,这年我们就不可能用linq to xml
等反系列化对象了。这一年就活该利用反射了。

二.真的开荒进程中,反射不是是向地方这么写的,真正的反光是应用组件来成功的,一般也不会选拔程序集反射,除非那个框架的某部作用模块更新往往,大家能够动用区别的反射区完毕,只需求在xml
文件中布局下就能够了。

三.在这里大致介绍下组件反射,不是说开拓进程中不会有程序集等反射,而是超过二分之壹的事态下组件反射就已经能知足咱们的急需了,如AutoFac组件,等别的的。

四.反射技艺点一般对应的手艺点有 IOC
翻转,重视倒置,重视注入等

上面分享壹篇作品,之所以写本文,就是因为上面那篇文小说介绍的太主流,大多人不会使用,Autofac是net
core 二.0内部的机件,请看下边包车型客车篇章

 

//格式  
//var builder = new ContainerBuilder();

           
//格式:builder.RegisterType<xxxx>().As<Ixxxx>().InstancePerLifetimeScope();

           //
builder.RegisterType<BasicInfo>().As<IBasicInfo>().InstancePerLifetimeScope();

        //    container = builder.Build();

 Autofac是八个轻量级的依附注入的框架,同体系的框架还有Spring.NET,Unity,Castle等。

  Autofac的施用有1个丰富令人烦恼的地方,就是服务器须要安装有Microsoft
.NET Framework 4
KB246887一。该补丁的地点是: 假设不设置,则运转程序会报如下错误:

  威尼斯人线上娱乐 20

  具体消息能够到这里去查看:

  那篇小说以叁个最简单易行的例证,开端Autofac的读书:

威尼斯人线上娱乐 21

namespace ConsoleApplication3{ class Program { static void Main(string[] args) { ContainerBuilder builder = newContainerBuilder();
builder.RegisterType<AutoFacManager>();
builder.RegisterType<Worker>().As<IPerson>(); using (IContainer container = builder.Build()) { AutoFacManager manager =
container.Resolve<AutoFacManager>(); manager.Say(); }
Console.ReadKey(); } } public interface IPerson { void Say(); } public class Worker IPerson { public void Say() {
Console.WriteLine(“作者是叁个工友!”); } } public class Student IPerson { public void Say() {
Console.WriteLine(“小编是一个学员!”); } } public class AutoFacManager { IPerson person; public AutoFacManager(IPerson MyPerson) { person = MyPerson; } public void Say() { person.Say(); }
}}

威尼斯人线上娱乐 22

  以上例子,是一个最简便易行的例子,输出如下:

  威尼斯人线上娱乐 23

  轻便解释:

  一、ContainerBuilder类型的成效

    组件通过ContainerBuilder的靶子注册。  

  2、组件

    对象急需从组件中来获得,举个例子例子中的Worker类的实例就必要从组件中赢得。

  3、哪些实例能够视作组件

  • Lambda表达式
  • 三个种类
  • 二个预编写翻译的实例
  • 实例类型所在的先后集

  4、容器

    ContainerBuilder的Build()方法能够成立轻便,从容器的Resolve()方法能够猎取对象。

  五、为了钦命组件服务是某1接口

    As()方法将用于注册时之钦命:builder.RegisterTye<TaskController>().As<TController>(); 
  6、组件的借助关系

    组件的依附关系主要透过接口完毕,如Worker:IPerson,

一、组件

  创制出来的指标急需从组件中来赢得,组件的创建有如下4种(接二连三第叁篇的德姆o,仅仅转移所贴出的代码)方式:

  壹、类型成立RegisterType

  AutoFac能够通过反射检查2个体系,采取2个适用的构造函数,创建那个指标的实例。主要透过RegisterType<T>()
和 RegisterType(Type) 七个措施以那种办法建设构造。

  ContainerBuilder使用 As() 方法将Component封装成了服务使用。

builder.RegisterType<AutoFacManager>();
builder.RegisterType<Worker>().As<IPerson>();

  二、实例成立

  builder.RegisterInstance<AutoFacManager>(new AutoFacManager(new Worker()));

  单例

  提供示范的情势,还有三个意义,便是不影响系统中原本的单例:

  builder.RegisterInstance(MySingleton.GetInstance()).ExternallyOwned();  //将自身系统中原本的单例注册为容器托管的单例

  那种方法会确认保证系统中的单例实例最后转化为由容器托管的单例实例。

  三、拉姆da表明式创设

  Lambda的办法也是Autofac通过反射的办法达成

builder.Register(c => new AutoFacManager(c.Resolve<IPerson>()));
builder.RegisterType<Worker>().As<IPerson>();

  四、程序集创设

  程序集的始建首要透过RegisterAssemblyTypes()方法达成,Autofac会自行在程序聚焦查找相称的类别用于成立实例。

builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()); //在此时此刻正在运作的先后聚集找builder.RegisterType<Worker>().As<IPerson>();

  伍、泛型注册

  泛型注册通过RegisterGeneric()
这些点子完毕,在轻便中能够创立出泛型的现实对象。

//泛型注册,能够透过容器重返List<T>
如:List<string>,List<int>等等builder.RegisterGeneric(typeof(List<>)).As(typeof(IList<>)).InstancePerLifetimeScope(); using (IContainer container = builder.Build()) { IList<string>
ListString = container.Resolve<IList<string>>();
}

  陆、暗中认可的挂号

  假使二个门类被反复登记,以最终注册的为准。通过行使PreserveExistingDefaults()
修饰符,能够钦点有些注册为非暗中同意值。

威尼斯人线上娱乐 24

ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<AutoFacManager>();
builder.RegisterType<Worker>().As<IPerson>();
builder.RegisterType<Student>().As<IPerson>().PreserveExistingDefaults();//钦点Student为非私下认可值 using (IContainer container = builder.Build()) { AutoFacManager
manager =
container.Resolve<AutoFacManager>(); manager.Say(); //输出自己是1个工友 }

威尼斯人线上娱乐 25

  假诺不使用PreserveExistingDefaults(),那么将出口“小编是2个学员”。

二、服务

  Autofac有三种标准的方法分别服务,同3个劳务的不等达成能够由项目,名称和键区分。

  1、类型

  类型是讲述服务的骨干办法

  builder.RegisterType<Worker>().As<IPerson>(); //IPerson类型的劳务和Worker的零部件连接起来,这么些服务能够创设Worker类的实例

  并且下面的劳动在机关器具中也卓有成效

  AutoFacManager manager =
container.Resolve<AutoFacManager>();

  2、名字

  服务能够进一步按名字识别。使用那种措施时,用
Named()注册格局替代As()以钦点名字:

  builder.RegisterType<Worker>().Named<IPerson>(“worker”);

  使用Name能够检索服务创立实例:

  IPerson p =
container.ResolveNamed<IPerson>(“worker”);

  ResolveNamed()只是Resolve()的简便重载,钦点名字的劳动实际是钦命键的劳动的粗略版本。

  3、键

  有Name的主意很有益,可是值支持字符串,但有时候大家恐怕供给通过其余品种作键。

  举个例子,使用枚举作为key:

  public enum DeviceState { Worker, Student }

  使用key注册服务,通过Keyed<T>()方法:

  builder.RegisterType<Student>().Keyed<IPerson>(DeviceState.Student);

  显式检索

  使用key检索服务以创设实例,通过ResolveKeyd()方法:

  IPerson p =
container.ResolveKeyed<IPerson>(DeviceState.Student);

   ResolveKeyd()会招致容器被当作 ServiceLocator使用,那是不被引入的。应该运用IIndex type取代。

   IIndex索引

  Autofac.Features.Indexed.IIndex<K,V>是Autofac自动实现的三个涉嫌类型。component能够采用IIndex<K,V>作为参数的构造函数从基于键的劳务中精选要求的兑现。

威尼斯人线上娱乐 26

builder.RegisterType<Student>().Keyed<IPerson>(DeviceState.Student); using (IContainer container = builder.Build())
{IIndex<DeviceStateIPerson> IIndex =
container.Resolve<IIndex<DeviceStateIPerson>>(); IPerson p = IIndex[DeviceState.Student];
p.Say(); //输出小编是2个上学的小孩子 }

威尼斯人线上娱乐 27

  IIndex中首先个泛型参数要跟注册时同样,在例子中是DeviceState枚举。其余两种注册格局未有如此的目录查找功效,那也是干什么设计者推荐Keyed注册的原由之壹。

3、自动装配

  从容器中的可用服务中甄选一个构造函数来创制对象,这几个进度叫做自动装配。这么些历程是由此反射实现的,所以其实容器创制对象的行为比较符合用在布局碰到中。

  一、采取构造函数

  Autofac暗许从容器中挑选参数最多的构造函数。若是想要选用1个见仁见智的构造函数,就须要在注册的时候就内定它。

  builder.RegisterType(typeof(Worker)).UsingConstructor(typeof(int));

  那种写法将点名调用Worker(int)构造函数,如该构造函数不设有则报错。

  二、额外的构造函数参数

  有三种艺术得以增添额外的构造函数参数,在注册的时候和在搜索的时候。在使用自动装配实例的时候这三种都会用到。

  挂号时抬高级参谋数

  使用WithParameters()方法在每贰遍创设对象的时候将零件和参数关联起来。

List<NamedParameter> ListNamedParameter = new List<NamedParameter>()
{ new NamedParameter(“Id”, 1), newNamedParameter(“Name”, “张三”) };
builder.RegisterType<Worker>().WithParameters(ListNamedParameter).As<IPerson>();

  在检索阶段加多参数
  在Resolve()的时候提供的参数会覆盖所盛名字同样的参数,在注册阶段提供的参数会覆盖容器中装有不小可能率的劳务。

  三、自动装配

  现今截止,自动装配最大的效益正是减弱重复配置。多数形似的component无论在哪儿注册,都可以透过扫描使用电动装配。

  builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).As<IPerson>();

  在急需的时候,依然得以成立钦点的构造函数创建钦点的类。

  builder.Register(c => new Worker(2,”关羽”));

4、程序集扫描

   1、扫描

  Autofac能够动用约定在程序聚焦登记或然搜索组件。

  Autofac能够依照用户钦点的规则在先后聚焦登记1多种的花色,那种办法叫做convention-driven
registration或许扫描。

  builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).Where(t
=> t.Name.EndsWith(“Manager”));

  每一种RegisterAssemblyTypes方法只可以应用一套规则。若是有多套分化的聚众要注册,那就有至关重要多次调用RegisterAssemblyTypes。

  二、选取项目

  RegisterAssemblyTypes接受程序集的集聚。私下认可景况下,程序集中拥有公共具体的类都会被登记。

  若是想要过滤注册的项目,能够选择Where.向上边那样:

  Where(t => t.Name.EndsWith(“Manager”))

  借使想要排除某个项目,使用Except():

  Except<AutoFacManager)>()

  可能,自定义那个早已去掉的品类的登记:

  Except<Worker>(ct
=>ct.As<IPerson>().SingleInstance())

  多个过滤器能够而且使用,那时他们之间是AND的关联。

  三、钦命服务

  RegisterAssemblyTypes那些注册方式是挂号单个方法的超集,所以类似As的法子也能够用在先后集中,比方

  As<IPerson>();

  As和Named那八个艺术额外的重载方法接受lambda表达式来控击溃务会提供如何的档案的次序。

五、事件

  一、激活事件

  在component生命周期的两样品级采纳事件。

  Autofac暴露三个事件接口供实例的按如下顺序调用

  1. OnRegistered
  2. OnPreparing
  3. OnActivated
  4. OnActivating
  5. OnRelease

  那么些事件会在登记的时候被订阅,恐怕被增大到IComponentRegistration
的时候。

builder.RegisterType<Worker>().As<IPerson>()
.OnRegistered(e =>
Console.WriteLine(“在注册的时候调用!”)) .OnPreparing(e =>
Console.WriteLine(“在希图开创的时候调用!”)) .OnActivating(e =>
Console.WriteLine(“在创制从前调用!”)) .OnActivated(e => Console.WriteLine(“创设之后调用!”))
.OnRelease(e =>
Console.WriteLine(“在假释占用的能源以前调用!”));

  以上示例输出如下:

  威尼斯人线上娱乐 28

  OnActivating

  组件被创立从前调用,在那边你能够:

  1. 将实例转向别的3个只怕采用代理封装它
  2. 进展质量注入
  3. 推行别的伊始化工作

  OnActivated

  在component被统统创立的时候调用一遍。在这年你能够推行顺序级其他一对办事(这个干活儿信赖于对象被全然成立)-那种意况很稀少。

  OnRelease

  取代component的标准清理措施。完结了IDisposable
接口的规范清理办法(未有标志为ExternallyOwned) 通过调用Dispose
方法。未有达成IDisposable只怕被标志为ExternallyOwned的清理办法是贰个空函数-不试行别的操作。OnRelease
正是用来掩盖私下认可的清理行为的。

6、属性注入

  属性注入使用可写属性而不是构造函数参数达成注入。

  示例:

builder.Register(c => new AutoFacManager { person =
c.Resolve<IPerson>() });
builder.RegisterType<Worker>().As<IPerson>();

  为了提供循环注重(就是当A使用B的时候B已经初阶化),要求动用OnActivated事件接口:

builder.Register(c => new AutoFacManager()).OnActivated(e =>
e.Instance.person = e.Context.Resolve<IPerson>());
builder.RegisterType<Worker>().As<IPerson>();

  通过反射,使用PropertiesAutowired()修饰符注入属性:

builder.RegisterType<AutoFacManager>().PropertiesAutowired();
builder.RegisterType<Worker>().As<IPerson>();

  要是您预先掌握属性的名字和值,你能够利用:

威尼斯人线上娱乐 ,builder.RegisterType<AutoFacManager>().WithProperty(“person”, new Worker());
builder.RegisterType<Worker>().As<IPerson>();

七、方法注入

  能够完结情势注入的艺术有三种。

  1、使用Activator

  倘若您采纳委托来激活,只要调用那几个办法在激活中

builder.Register(c => { var result = new AutoFacManager();
result.SetDependency(c.Resolve<IPerson>()); return result;
});

  注意,使用那种措施,AutoFacManager类里总得要有其一艺术:

public void SetDependency(IPerson MyPerson) { person = MyPerson;
}

  2、使用Activating Handler

  如若你利用此外一种激活,比方反射激活,创设激活的轩然大波接口OnActivating,那种措施仅需一行代码:

  builder.Register<AutoFacManager>(c => new AutoFacManager()).OnActivating(e
=> e.Instance.SetDependency(newWorker()));

八、Resolve的参数

  当注册大概检索component的时候能够动用参数。

  壹、传递参数给Resolve

  Resolve接受可变参数或IEnumerable<T>传入多少个值

using (IContainer container = builder.Build()) { AutoFacManager manager =
container.Resolve<AutoFacManager>(newNamedParameter(“name”, “刘备”)); Console.WriteLine(manager.Name); //输出 刘备 manager.Say();
}

  此时,AutoFacManager下必须加多如下构造函数

public AutoFacManager(string name,IPerson MyPerson) { Name = name; person = MyPerson;
}

  二、可用的参数类型

  Autofac提供二种区别的参数对应政策:

  1. NamedParameter :像下边那样对应的参数名字
  2. TypedParameter:对应到参数的体系(必须是有血有肉的品类)
  3. ResolvedParameter:灵活的参数相称
  4. NamedParameter 和TypedParameter:只好提供常量参数

  3、从表明式中央银行使参数

  假诺利用表明式注册的秘技,能够应用第三个可用的嘱托参数来取得参数。

威尼斯人线上娱乐 29

builder.Register((c, p) => new AutoFacManager(p.Named<string>(“name”),
c.Resolve<IPerson>()));
builder.RegisterType<Worker>().As<IPerson>(); using (IContainer container = builder.Build()) { AutoFacManager manager =
container.Resolve<AutoFacManager>(new NamedParameter(“name”, “刘备”)); Console.WriteLine(manager.Name); //输出汉烈祖 manager.Say();
}

威尼斯人线上娱乐 30

九、元数据

  Autofac提供部分体制去创立和使用component的元数据。元数据是储存component中的关于这一个component的音讯,无需创设实例也能访问。

  ①、在注册的时候增加元数据

  值描述的元数据在登记阶段和component联系起来,各种元数据都以3个键值对:

builder.RegisterType<AutoFacManager>();
builder.Register(c => new Worker()).As<IPerson>().WithMetadata(“大将”, “赵云”);

  用XML文件可以象征为:

威尼斯人线上娱乐 31

  <component   type=”ConsoleApplication3.Program.Worker,
ConsoleApplication3″   service=”ConsoleApplication3.Program.IPerson,
ConsoleApplication3″ >   <metadata>   <item name=”大将” value=”赵云” type=”System.String” />   </metadata>  </component>

威尼斯人线上娱乐 32

  二、使用元数据

  不用于一般的习性,元数据和component自个儿是彼此独立额度。

  那使得在运作条件下从众多component中甄选1个时10分有用,恐怕元数据不是component实例的原有属性时。元数据能够公布ITask
试行的时光,可能完成了ICommand的开关标题。

  此外一些component能够经过Meta 使用元数据。

拾、循环依赖

  循环正视是指运营时期对象时期的相互依赖

  方今,Autofac仅仅由拍卖构造函数/属性依赖的章程。

  一、构造函数/属性正视

   使用含有属性信赖的类时,使用Activated事件的InjectUnsetProperties。

威尼斯人线上娱乐 33

  public class Student  {   public Student(Worker worker) { }  }   public class Worker  {   public Student Student { get; set; }  }   ContainerBuilder cb = new ContainerBuilder();  cb.Register<Student>();  cb.Register<Worker>().OnActivated(ActivatedHandler.InjectUnsetProperties);

威尼斯人线上娱乐 34

十一、泛型

  给定一个开花的泛型,Autofac会提供三个现实的贯彻。

  开放的泛型类型应用泛型服务注册必要给定3个服务类型和3个兑现项目。

builder.RegisterGeneric(typeof(List<>)).As(typeof(IList<>)); using (IContainer container = builder.Build()) { var tt =
container.Resolve<IList<int>>();
Console.WriteLine(tt.GetType().FullName);
}

  Autofac关怀泛型约束。即使一个有约束的兑现项目对服务不可用,那么这么些实现项目将被忽略。

10二、适配器和装饰器

  Autofac提供一些机制来促成适配器格局和装饰器格局。

  1、适配器

  一个适配器使用二个劳动并且适配别的贰个。
  假设多少个适配器在Autofac中被登记,Autofac会为每一种适配服务的贯彻创制单独的适配器。
  那几个介绍性的篇章讲述了适配器在Autofac中是什么样完结的。

  2、装饰器

  装饰器像适配器同样,在里边封装了1个实际的劳动的落实,不过和适配器比较,装饰器暴暴光的服务和它包裹的平等。

拾三、实例生命周期

  实例生命周期决定在同3个服务的各类请求的实例是怎么共享的。

  当呼吁三个劳务的时候,Autofac会回去一个单例 (single instance功效域),
3个新的指标 (per lifetime功用域) 也许在某种上下文景况中的单例。比方3个线程 也许二个HTTP请求 (per lifetime 功能域)。

  那条规则适用于显式调用Resolve从容器中索求对象也许满足重视而隐式达成的指标。

  1、Per Dependency

  在其余容器中也称作须臾态也许工厂,使用Per
Dependency效用域,服务对于每一趟请求都会回去互补影响实例。

  在未曾点名别的参数的事态下,这是暗中认可是效用域。

  builder.RegisterType<Worker>();   // or   builder.RegisterType<Worker>().InstancePerDependency();

  2、Single Instance

  使用Single
Instance功效域,所有对父容器可能嵌套容器的请求都会回去同1个实例。

  builder.RegisterType<Worker>().SingleInstance();

  3、Per Lifetime Scope

  这一个作用域适用于嵌套的生命周期。一个利用Per Lifetime
作用域的component在2个 nested lifetime scope内最多有三个实例。

  当目的特定于一个工作单元时,这一个尤其管用。比方,2个HTTP请求,每一个行事单元都会成立一个nested
lifetime,即使在每三次HTTP请求中开创叁个nested lifetime,那么别的应用
per-lifetime 的component在历次HTTP请求中只会具备一个实例。

  那种安排模型在任何容器中等价于per-HTTP-request, per-thread等。

  builder.RegisterType<Worker>().InstancePerLifetimeScope();

  ASP.NET和WCF集成人中学,每2遍web请求或然措施调用,InstancePerLifetimeScope会被默许附加到component上。

   4、上下文

  上下文功效域和per-lifetime功效域类似,不过对可知性提供越多展现的主宰。

  在大多程序中,同1档期的顺序的容器嵌套代表四个行事单元,即使须要多层嵌套(比如global->request->transation),能够选取标签确认保障component在多层结构中的某一层共享。

  builder.RegisterType<XWorker>().InstancePerMatchingLifetimeScope(MyContextHierarchy.UserSession);

  提供的标签和生命周期作用域是对应的

  var userSessionLifetime = container.BeginLifetimeScope(); 

  userSessionLifetime.Tag =
MyContextHierarchy.UserSession;

1、基本配备

  一、通过配备的章程使用Autofac

威尼斯人线上娱乐 35

  <?xml version=”1.0″?>  <configuration>   <configSections>   <section name=”autofac” type=”Autofac.Configuration.SectionHandler,
Autofac.Configuration”/>   </configSections>   <autofac defaultAssembly=”ConsoleApplication3″>   <components>   <component type=”ConsoleApplication3.Worker,
ConsoleApplication3″ service=”ConsoleApplication3.IPerson” />   </components>   </autofac>  </configuration>

威尼斯人线上娱乐 36

  二、通过RegisterModule形式采取布署文件中的音讯

威尼斯人线上娱乐 37

static void Main(string[] args) { ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<AutoFacManager>();
builder.RegisterModule(new ConfigurationSettingsReader(“autofac”)); using (IContainer container = builder.Build()) { AutoFacManager manager =
container.Resolve<AutoFacManager>(); manager.Say(); } Console.ReadKey();
}

威尼斯人线上娱乐 38

  3、通过Register的方式

builder.RegisterModule(new ConfigurationSettingsReader(“autofac”));
builder.Register(c => newAutoFacManager(c.Resolve<IPerson>()));

 原文  

 


相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图