公司不用任何IOC,ORM框架,只好自己没事学学.

可能有些语言描述的不专业

希望能有点用

namespace Autofac
{
    class Program
    {
        //声明一个容器
        private static IContainer container;
        static void Main(string[] args)
        {

            #region 入门示例 1

            {
                ////注册 Autofac 组件
                //var builder = new ContainerBuilder();

                ////注册 ConsoleOutput 组件, 提供 IOutput 服务
                //builder.RegisterType<ConsoleOutput>().As<IOutput>();

                ////注册 TodayWriter 组件, 提供 IDateWriter 服务
                //builder.RegisterType<TodayWriter>().As<IDateWriter>();

                ////创造一个容器
                //container = builder.Build();

                //using (ILifetimeScope scope = container.BeginLifetimeScope())
                //{
                //    IDateWriter dateWriter = scope.Resolve<IDateWriter>();
                //    dateWriter.Write();
                //}

            }

            #endregion

            #region 入门实例 2

            {
                //var builder = new ContainerBuilder();
                //builder.RegisterType<Person>();
                //container = builder.Build();
                //Person person;
                //using (var scope = container.BeginLifetimeScope())
                //{
                //    person = scope.Resolve<Person>();
                //}
                //person.Print();
            }

            #endregion

            #region 自动选择合适的构造函数注入

            {
                //var builder = new ContainerBuilder();

                ////这里只注册了 ConsoleOutput ,没有注册 ILogger 类型的实例
                //builder.RegisterType<ConsoleOutput>().As<IOutput>();

                //builder.RegisterType<TodayWriter>().As<IDateWriter>();
                //container = builder.Build();
                //IDateWriter writer;
                //using (var scope = container.BeginLifetimeScope())
                //{
                //    //当我们"决定"要一个 IDateWriter 接口类型的实例时,autofac会在容器里面寻找注册过的 IDateWriter 接口类型
                //    //当它找到 TodayWriter,并准备创建 TodayWriter 类型的实例时,发现有三个构造函数,分别接收 0个,1个,2个参数
                //    //这时候,autofac 会先尝试执行2个参数的构造函数,结果发现容器里面没有注册过 ILogger 接口类型的实现类
                //    //于是接着尝试执行1个参数的构造函数,当然,我们注册了 ConsoleOutput 类,这里肯定能找到,于是就用1个参数的构造函数创造了一个 TodayWriter 的实例
                //    //这点跟 Unity 是一样的.
                //    writer = scope.Resolve<IDateWriter>();
                //}
                //writer.Write();
            }

            #endregion

            #region 手动指定构造函数注入

            {
                //var builder = new ContainerBuilder();

                //builder.RegisterType<ConsoleOutput>().As<IOutput>();
                //builder.RegisterType<DataLogger>().As<ILogger>();

                ////builder.RegisterType<TodayWriter>().As<IDateWriter>();
                ////手动指定要执行的构造函数
                //builder.RegisterType<TodayWriter>().As<IDateWriter>().UsingConstructor(typeof(IOutput));

                //container = builder.Build();
                //IDateWriter writer;
                //using (var scope = container.BeginLifetimeScope())
                //{
                //    writer = scope.Resolve<IDateWriter>();
                //}
                //writer.Write();
            }

            #endregion

            #region 注册实例到容器中

            {
                //var builder = new ContainerBuilder();

                //var output = new ConsoleOutput();
                ////当您执行此操作时,需要考虑的事情是 Autofac 自动处理注册组件的处理,您可能希望自己控制自己的生命周期,而不是让 Autofac 自动调用对您的对象的处理.
                ////在这种情况下,您需要使用 ExternallyOwned 方法注册该实例
                //builder.RegisterInstance(output).As<IOutput>().ExternallyOwned();

                //builder.RegisterType<TodayWriter>().As<IDateWriter>();
                //container = builder.Build();
                //IDateWriter writer;
                //using (var scope = container.BeginLifetimeScope())
                //{
                //    writer = scope.Resolve<IDateWriter>();
                //}
                //writer.Write();
            }

            #endregion

            #region Lambda表达式 注入

            {
                //var builder = new ContainerBuilder();
                ////Register 为 Lambda表达式组件 注入
                ////参数c是其中正在创建组件的组件上下文(IComponentContext对象)
                //builder.Register(c => new TodayWriter(c.Resolve<IOutput>()));

                ////RegisterType 为 反射组件 注入
                ////后注册也没关系,真正生效是在  builder.Build() 创建容器的时候.
                //builder.RegisterType<ConsoleOutput>().As<IOutput>();

                //container = builder.Build();
                //IDateWriter writer;
                //using (var scope = container.BeginLifetimeScope())
                //{
                //    writer = scope.Resolve<TodayWriter>();
                //}
                //writer.Write();
            }

            #endregion

            #region 注入泛型

            {
                //var builder = new ContainerBuilder();

                ////注册泛型
                //builder.RegisterGeneric(typeof(MySql<>)).As(typeof(IDal<>)).InstancePerLifetimeScope();

                ////我们假设要创建 泛型参数为 Person 的 Mysql<> 类的实例
                //builder.RegisterType<Person>();

                ////Person 需要 IDataWriter
                //builder.RegisterType<TodayWriter>().As<IDateWriter>();

                ////TodayWriter 需要 IOutput
                //builder.RegisterType<ConsoleOutput>().As<IOutput>();

                //container = builder.Build();
                //IDal<Person> dal;
                //using (var scope = container.BeginLifetimeScope())
                //{
                //    dal = scope.Resolve<IDal<Person>>();
                //}
                //dal.Pint();
            }

            #endregion

            #region 组件和服务

            {
                //var builder = new ContainerBuilder();

                //////注册组件时,必须告诉 Autofac ,注册的组件需要暴露哪些服务。 默认情况下,大多数注册只会将自己公开为注册类型
                ////builder.RegisterType<Person>();

                //////也可以 同时 暴露其他服务
                ////builder.RegisterType<Person>().As<Human>();

                ////这行代码是上面两行代码的简写
                //builder.RegisterType<Person>().AsSelf().As<Human>();

                ////也可以使用任意数量的服务来显示组件:
                //builder.RegisterType<Student>().As<ILogger>().As<IOutput>();

                //container = builder.Build();
                //ILogger loggerWriter;
                //IOutput outputWriter;
                //using (var scope = container.BeginLifetimeScope())
                //{
                //    Human human = scope.Resolve<Human>();
                //    Person person = scope.Resolve<Person>();
                //    loggerWriter = scope.Resolve<ILogger>();
                //    outputWriter = scope.Resolve<IOutput>();
                //}
                //loggerWriter.LoggerPrint();
                //outputWriter.OutputPrint();
            }

            #endregion

            #region 默认注册的组件

            {
                //var builder = new ContainerBuilder();

                ////这里注册了2个组件,ConsoleOutput 和 DataLogger ,他们公开了相同的服务 IWriter
                //builder.RegisterType<ConsoleOutput>().As<IWriter>();
                ////这里会覆盖上面注册的组件
                //builder.RegisterType<DataLogger>().As<IWriter>();

                ////设置已经注册过的组件作为 服务 IWriter 的默认提供程序
                ////新注册的组件不会再覆盖已注册的组件
                ////也就是说,下面解析的时候,会创建 ConsoleOutput 的对象作为 IWriter 的实例
                ////builder.RegisterType<DataLogger>().As<IWriter>().PreserveExistingDefaults();

                //container = builder.Build();
                //IWriter writer;
                //using (var scope = container.BeginLifetimeScope())
                //{
                //    //Autofac 会默认使用最后注册的组件作为该服务的默认提供程序
                //    //也就是说,这里会默认创建 DataLogger 的对象作为 IWriter 的实例
                //    writer = scope.Resolve<IWriter>();
                //}
                //writer.Write();
            }

            #endregion

            #region  有条件的注册组件

            {
                //var builder = new ContainerBuilder();

                //builder.RegisterType<Person>().AsSelf().As<Human>();

                ////如果还没有注册 Human 服务的组件,则注册 Student,提供 ILogger 服务
                //builder.RegisterType<Student>().As<ILogger>().IfNotRegistered(typeof(Human));

                ////如果还没有注册 Person 服务的组件,则注册 Student,提供 ILogger 服务
                //builder.RegisterType<Student>().As<ILogger>().IfNotRegistered(typeof(Person));

                ////如果还没有注册 ILogger 服务的组件,则注册 TodayWriter,提供 IDateWriter 服务
                //builder.RegisterType<ConsoleOutput>().As<IOutput>().IfNotRegistered(typeof(ILogger));

                //container = builder.Build();
                //using (var scope = container.BeginLifetimeScope())
                //{
                //    Human human = scope.Resolve<Human>();
                //    Person person = scope.Resolve<Person>();
                //    IOutput output = scope.Resolve<IOutput>();
                //    try
                //    {
                //        ILogger student = scope.Resolve<ILogger>();
                //    }
                //    catch (Exception)
                //    {
                //        Console.WriteLine("还没有注册任何组件来提供 ILogger 服务");
                //    }
                //}
            }

            #endregion

            #region 带参数的注入

            {
                //var builder = new ContainerBuilder();

                ////注册组件时传入参数值的三种方式:
                ////builder.RegisterType<Person>().WithParameter(parameterName: "personName", parameterValue: "wjire");
                ////builder.RegisterType<Person>().WithParameter(new TypedParameter(typeof(string), "wjire2"));
                ////builder.RegisterType<Person>().WithParameter(new ResolvedParameter((p, c) => p.ParameterType == typeof(string) && p.Name.Equals("personName"), (p, c) => "wjire3"));

                ////注册时不传,解析时传入参数值得方式:
                ////使用lambda表达式注册组件,不需要在注册时传入参数值,而是声明需要传入的参数值的名称
                ////具体的参数值是在解析的时候传入.
                ////builder.Register((c, p) => new Person(p.Named<string>("parameterName")));

                ////最简单的写法:
                //builder.RegisterType<Person>();

                //container = builder.Build();
                //using (var scope = container.BeginLifetimeScope())
                //{
                //    //这种是在注册时就传入参数
                //    //Person person = scope.Resolve<Person>();

                //    //这是lambda表达式组件在解析时传入参数的方式
                //    //Person person = scope.Resolve<Person>(new NamedParameter("parameterName", "海尔兄弟"));

                //    //这是最简单的方法
                //    //Person person = scope.Resolve<Person>(new ResolvedParameter((p, c) => p.ParameterType == typeof(string) && p.Name.Equals("personName"), (p, c) => "玫瑰花蕾"));
                //    //Person person = scope.Resolve<Person>(new TypedParameter(typeof(string), "猫和老鼠"));
                //    Person person = scope.Resolve<Person>(new NamedParameter("personName", "海尔兄弟"));

                //    person.PrintWithParameter("refuge");
                //}
            }

            #endregion

            #region 属性注入

            {
                //var builder = new ContainerBuilder();
                //builder.RegisterType<ConsoleOutput>().As<IOutput>();

                ////反射组件方式:
                ////builder.RegisterType<TodayWriter>().As<IDateWriter>().PropertiesAutowired();

                ////lambda表达式组件方式:
                //builder.Register(c => new TodayWriter { output = c.Resolve<IOutput>() }).As<IDateWriter>();

                //container = builder.Build();
                //using (var scope = container.BeginLifetimeScope())
                //{
                //    //不会执行 含有 IOutput 类型的参数的构造函数
                //    IDateWriter writer = scope.Resolve<IDateWriter>();
                //    writer.Write();
                //}
            }

            #endregion

            #region 方法注入

            {
                //var builder = new ContainerBuilder();
                //builder.RegisterType<ConsoleOutput>().As<IOutput>();
                //builder.RegisterType<DataLogger>().As<ILogger>();

                //// 使用 lambda 表达式组件,并在激活器中处理方法调用:
                //builder.Register(c =>
                //{
                //    var result = new TodayWriter();
                //    var iOutput = c.Resolve<IOutput>();
                //    var iLogger = c.Resolve<ILogger>();
                //    result.SetPropertyValue(iOutput, iLogger);
                //    return result;
                //}).As<IDateWriter>();

                //container = builder.Build();
                //using (var scope = container.BeginLifetimeScope())
                //{
                //    IDateWriter writer = scope.Resolve<IDateWriter>();
                //    writer.Write();
                //}
            }

            #endregion

            #region 注册程序集中的类型

            {
                //var builder = new ContainerBuilder();

                ////获取当前程序集
                //var dataAccess = Assembly.GetExecutingAssembly();

                ////注册程序集中所有具有无参数构造函数的公共具体类
                //builder.RegisterAssemblyTypes(dataAccess);

                //container = builder.Build();
                //using (var scope = container.BeginLifetimeScope())
                //{
                //    Person p = scope.Resolve<Person>();
                //    Student s = scope.Resolve<Student>();
                //    try
                //    {
                //        Dog d = scope.Resolve<Dog>();
                //    }
                //    catch (Exception)
                //    {
                //        Console.WriteLine($"{typeof(Dog)} 没有无参的构造函数");
                //    }

                //    try
                //    {
                //        p.Print();
                //    }
                //    catch (Exception)
                //    {
                //        Console.WriteLine("属性 dateWriter 为 null,因为它声明的是 IDateWriter 接口类型,不是具体类,所以没有被注册");
                //    }
                //}
            }

            {
                //var dataAccess = Assembly.GetExecutingAssembly();
                //var builder = new ContainerBuilder();

                ////注册所有接口类型
                //builder.RegisterAssemblyTypes(dataAccess).AsImplementedInterfaces();

                //container = builder.Build();
                //using (var scope = container.BeginLifetimeScope())
                //{
                //    //解析的时候,只会解析出一种实现类.
                //    //具体解析出哪一种,暂时还没发现规律.
                //    IWriter writer = scope.Resolve<IWriter>();
                //    writer.Write();
                //}
            }

            {
                //var dataAccess = Assembly.GetExecutingAssembly();
                //var builder = new ContainerBuilder();

                ////注册所有 ILogger 接口类型
                //builder.RegisterAssemblyTypes(dataAccess).As<ILogger>();

                //container = builder.Build();
                //using (var scope = container.BeginLifetimeScope())
                //{
                //    ILogger writer = scope.Resolve<ILogger>();
                //    writer.Write();
                //    try
                //    {
                //        Person p = scope.Resolve<Person>();
                //    }
                //    catch (Exception)
                //    {
                //        Console.WriteLine($"{typeof(Person)} 没有注册");
                //    }
                //}
            }

            #endregion

            #region 过滤程序集中的类型

            {
                //var dataAccess = Assembly.GetExecutingAssembly();
                //var builder = new ContainerBuilder();

                ////利用谓词过滤类型
                ////builder.RegisterAssemblyTypes(dataAccess).Where(w => w.Name.StartsWith("P"));

                ////排除 Person 类型
                //builder.RegisterAssemblyTypes(dataAccess).Except<Person>();

                //container = builder.Build();
                //using (var scope = container.BeginLifetimeScope())
                //{
                //    try
                //    {
                //        Person p = scope.Resolve<Person>();
                //    }
                //    catch (Exception)
                //    {
                //        Console.WriteLine($"{typeof(Person)} 没有注册");
                //    }
                //    try
                //    {
                //        Student s = scope.Resolve<Student>();
                //    }
                //    catch (Exception)
                //    {
                //        Console.WriteLine($"{typeof(Student).Name} 不是以 'P' 开头");
                //    }
                //}
            }

            #endregion

            #region 模块扫描

            #endregion

            #region 实例范围

            #region 每次解析都创建一个新的实例

            //{
            //    var builder = new ContainerBuilder();

            //    builder.RegisterType<TodayWriter>().As<IDateWriter>();

            //    container = builder.Build();
            //    using (var scope = container.BeginLifetimeScope())
            //    {
            //        //每次循环都将创建一个新的实例
            //        for (var i = 0; i < 100; i++)
            //        {
            //            IDateWriter writer = scope.Resolve<IDateWriter>();
            //        }
            //    }
            //}

            #endregion

            #region 在当前生命周期范围内单例,不包含嵌套的生命周期范围(嵌套的算新的)

            //{
            //    var builder = new ContainerBuilder();

            //    //在当前生命周期范围内是单例,构造函数只会执行一次,局部单例   New scope = new instance
            //    builder.RegisterType<TodayWriter>().As<IDateWriter>().InstancePerLifetimeScope();

            //    container = builder.Build();
            //    using (var scope1 = container.BeginLifetimeScope())
            //    {
            //        for (var i = 0; i < 100; i++)
            //        {
            //            //当前生命周期范围内只创建一次对象
            //            IDateWriter writer1 = scope1.Resolve<IDateWriter>();

            //            //尽管每次循环都是在 scope1 生命周期范围内嵌套的生命周期范围
            //            //但每次循环,下面依然会创建一个新的对象
            //            using (var scope2 = scope1.BeginLifetimeScope())
            //            {
            //                IDateWriter writer2 = scope2.Resolve<IDateWriter>();
            //            }
            //        }
            //    }
            //}

            #endregion

            #region 在指定的生命周期范围内单例,注意与上面的区别

            //{
            //    var builder = new ContainerBuilder();

            //    builder.RegisterType<TodayWriter>().As<IDateWriter>().InstancePerMatchingLifetimeScope("myScope");

            //    container = builder.Build();
            //    using (var scope1 = container.BeginLifetimeScope("myScope"))
            //    {
            //        for (var i = 0; i < 100; i++)
            //        {
            //            IDateWriter writer1 = scope1.Resolve<IDateWriter>();

            //            //尽管每次都嵌套了一个新的生命周期范围
            //            //但它依然属于名为"myScope"的生命周期范围
            //            //因为它是嵌套在"myScope"的生命周期范围内的
            //            //所以是单例
            //            using (var scope2 = scope1.BeginLifetimeScope())
            //            {
            //                IDateWriter writer2 = scope2.Resolve<IDateWriter>();
            //            }
            //        }
            //    }

            //    //但是下面会创建一个新的实例
            //    //因为它是另外一个名叫"myScope"的生命周期范围
            //    using (var scope1 = container.BeginLifetimeScope("myScope"))
            //    {
            //        for (var i = 0; i < 100; i++)
            //        {
            //            IDateWriter writer1 = scope1.Resolve<IDateWriter>();

            //            using (var scope2 = scope1.BeginLifetimeScope())
            //            {
            //                IDateWriter writer2 = scope2.Resolve<IDateWriter>();
            //            }
            //        }
            //    }
            //}

            #endregion

            #region 终生单例

            //{
            //    var builder = new ContainerBuilder();

            //    //终生单例,构造函数只会执行一次
            //    builder.RegisterType<TodayWriter>().As<IDateWriter>().SingleInstance();

            //    container = builder.Build();
            //    using (var scope1 = container.BeginLifetimeScope())
            //    {
            //        for (var i = 0; i < 100; i++)
            //        {
            //            IDateWriter writer1 = scope1.Resolve<IDateWriter>();
            //            using (var scope2 = container.BeginLifetimeScope())
            //            {
            //                IDateWriter writer2 = scope2.Resolve<IDateWriter>();
            //            }
            //        }
            //    }
            //}

            #endregion

            #region 每次请求单例

            {
                //var builder = new ContainerBuilder();

                //Asp.Net MVC中才能使用
                //builder.RegisterType<TodayWriter>().As<IDateWriter>().InstancePerRequest();
            }

            #endregion

            #region 依赖于某个组件的实例

            //{
            //    var builder = new ContainerBuilder();

            //    builder.RegisterType<TodayWriter>().As<IDateWriter>().InstancePerOwned<Person>();

            //    builder.RegisterType<Person>().UsingConstructor(typeof(IDateWriter));

            //    container = builder.Build();
            //    using (var scope = container.BeginLifetimeScope())
            //    {
            //        var owned = scope.Resolve<Owned<Person>>();
            //        Person p = owned.Value;
            //        try
            //        {
            //            IDateWriter writer = scope.Resolve<IDateWriter>();
            //        }
            //        catch (Exception)
            //        {
            //            Console.WriteLine("不能单独解析 IDateWriter ,因为它的生命周期范围只存在于解析 Person 组件时");
            //        }
            //        owned.Dispose();
            //    }
            //}

            #endregion

            #region 线程范围,还没有深入的理解,目前看来,本质就是当前生命周期范围内的单例

            {
                var builder = new ContainerBuilder();

                builder.RegisterType<TodayWriter>().As<IDateWriter>().InstancePerLifetimeScope();

                container = builder.Build();

                Task.Run(() =>
                {
                    using (var scope = container.BeginLifetimeScope())
                    {
                        IDateWriter thisThreadInstance = scope.Resolve<IDateWriter>();
                    }
                });

                Task.Run(() =>
                {
                    using (var scope = container.BeginLifetimeScope())
                    {
                        IDateWriter thisThreadInstance = scope.Resolve<IDateWriter>();
                    }
                });
            }

            #endregion

            #endregion

            Console.ReadKey();
        }
    }
}

转网上一段总结:

1.依赖注入的目的是为了解耦。

2.不依赖于具体类,而依赖抽象类或者接口,这叫依赖倒置。

3.控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器

Autofac 简单示例的更多相关文章

  1. ioc autofac简单示例

    1.winform用法: nuget安装autofac public interface ILog { bool Log(string msg); } public class TXTLogger : ...

  2. 基于.NET CORE微服务框架 -surging的介绍和简单示例 (开源)

    一.前言 至今为止编程开发已经11个年头,从 VB6.0,ASP时代到ASP.NET再到MVC, 从中见证了.NET技术发展,从无畏无知的懵懂少年,到现在的中年大叔,从中的酸甜苦辣也只有本人自知.随着 ...

  3. AutoFac简单入门

    AutoFac是.net程序下一个非常灵活易用,且功能强大的DI框架,本文这里简单的介绍一下使用方法. 安装: Install-Package Autofac 简单的示例: static void M ...

  4. Linux下的C Socket编程 -- server端的简单示例

    Linux下的C Socket编程(三) server端的简单示例 经过前面的client端的学习,我们已经知道了如何创建socket,所以接下来就是去绑定他到具体的一个端口上面去. 绑定socket ...

  5. C# 构建XML(简单示例)

    C# 构建XML的简单示例: var pars = new Dictionary<string, string> { {"url","https://www. ...

  6. 根据juery CSS点击一个标签弹出一个遮罩层的简单示例

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  7. ACEXML解析XML文件——简单示例程序

    掌握了ACMXML库解析XML文件的方法后,下面来实现一个比较完整的程序. 定义基本结构 xml文件格式如下 <?xml version="1.0"?> <roo ...

  8. demo工程的清单文件及activity中api代码简单示例

    第一步注册一个账户,并创建一个应用.获取app ID与 app Key. 第二步下载sdk 第三步新建工程,修改清单文件,导入相关的sdk文件及调用相应的api搞定. 3.1 修改清单文件,主要是加入 ...

  9. spring-servlet.xml简单示例

    spring-servlet.xml简单示例 某个项目中的spring-servlet.xml 记下来以后研究用 <!-- springMVC简单配置 --> <?xml versi ...

随机推荐

  1. 笔记-JS高级程序设计-基本概念篇

    1:JS中的一切(变量,函数名和操作符)都是区分大小写的 2:标识符(变量,函数,属性的名字,以及函数的参数),第一个字符必须是字母,下划线,或者美元$,书写方式采用驼峰式,不能将关键字作为标识符. ...

  2. Redis主从配置及HA方案

    首先说下主从同步Replication的原理 在Slave启动并连接到Master之后,它将主动发送一条SYNC命令.此后Master将启动后台存盘进程,同时收集所有接收到的用于修改数据集的命令,在后 ...

  3. BaaS 的由来(1)

    百度百科是这么定义的, BaaS(后端即服务:Backend as a Service)公司为移动应用开发者提供整合云后端的边界服务.其实不仅是移动应用,现在更多的PC应用也同样适用移动端的标准. 在 ...

  4. PetaPoco批量插入数据

    VS添加完组件,自动生成的PetaPoco.cs文件中没有SqlBulkInsert这个方法,但是可以在里面添加,代码如下: /// <summary> /// BulkInsert // ...

  5. 图像实验室 website 项目日志

    day 1 1.问题: 在演示界面选择浏览本地图片,上传以后不显示上传图片 原因:PIL库没有装好,参见之前博客重装 2.问题: 可以上传图片并在网站上显示,但是不能得到运行结果的图片. 原因:没有将 ...

  6. java-StringBuffer学习笔记

    字符串是敞亮,它们的值在创建之后不能更改字符串的内容一旦发生了变化,那么马上回创建一个新的对象 public class Demo1{ public static void main(String[] ...

  7. 在Editplus中配置java的(带包)编译(javac)和运行(java)的方法

    配置的前提是电脑安装了JDK并且配置好了相关的环境变量(JAVA_HOME,path和classpath). 配置好后在命令行中输入javac和java验证是否配置成功: 如果出现上面的情况则说明配置 ...

  8. 解决浏览器兼容ES6特性

    为什么ES6会有兼容性问题? 由于广大用户使用的浏览器版本在发布的时候也许早于ES6的定稿和发布,而到了今天,我们在编程中如果使用了ES6的新特性,浏览器若没有更新版本,或者新版本中没有对ES6的特性 ...

  9. CSS( Cascading Style Sheets )简书

    (注:带*号的属性是CSS3新增属性)一.基本规则1.css通常存储在样式表(style)中,用于定义如何显示HTML元素:2.css主要由两个部分构成:选择器和一条或多条声明. 选择器通常是需要改变 ...

  10. php后台开源框架

    1,OneBase 官网首页:https://onebase.org 后台演示:https://demo.onebase.org/admin.php 接口演示:https://demo.onebase ...