C#使用Unity实现IOC

一、什么是IOC

学习IOC之前先来了解一个依赖导致原则(DIP),依赖导致原则是IOC的核心原理。

依赖导致:即上层模块不应该依赖于低层模块,二者应该通过抽象来依赖。依赖于抽象,而不是依赖于细节。

首先来看下面的例子:

1、定义一个接口,封装数据库的基本CRUD操作,接口定义如下:

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

namespace DataBase.Interface
{
    /// <summary>
    /// 数据访问接口
    /// </summary>
   public  interface IDbInterface
    {
        string Insert();
        string Delete();
        string Update();
        string Query();
    }
}

2、定义一个MSSQL类实现该接口,用来模仿SQLServer操作,MSSQL类定义如下:

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

namespace DataBase.MSSQL
{
    public class DbMSSQL : IDbInterface
    {
        public string Delete()
        {
            return "MSSQL执行删除";
        }

        public string Insert()
        {
            return "MSSQL执行插入";
        }

        public string Query()
        {
            return "MSSQL执行查询";
        }

        public string Update()
        {
            return "MSSQL执行更新";
        }
    }
}

3、定义一个Oracle类实现该接口,模仿Oracle的操作,Oracle类定义如下:

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

namespace DataBase.Oracle
{
    public class DbOracle : IDbInterface
    {
        public string Delete()
        {
            return "Oracle执行删除";
        }

        public string Insert()
        {
            return "Oracle执行插入";
        }

        public string Query()
        {
            return "Oracle执行查询";
        }

        public string Update()
        {
            return "Oracle执行更新";
        }
    }
}

4、定义一个控制台应用程序来调用:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DataBase.Interface;
using DataBase.MSSQL;

namespace IOCConApp
{
    class Program
    {
        static void Main(string[] args)
        {
            // 常规做法,即程序的上端,依赖于下端,依赖于细节
            DbMSSQL mssql = new DbMSSQL();
        }
    }
}

常规做法是添加引用,然后直接实例化类,但是这样会依赖于细节实现,现将代码修改如下:

// 通过抽象来依赖
IDbInterface dbInterface = new DbMSSQL();

但是这样修改以后,虽然左边是抽象了,但是右边还是依赖于细节。

那就究竟什么是IOC呢?

IOC(Inversion of Control)即控制反转,是一个重要的面向对象编程的法则来消减程序之间的耦合问题,把程序中上层对下层依赖,转移到一个第三方容器中来装配。IOC是程序设计的目标,实现方式包含依赖注入和依赖查找,在.net中只有依赖注入。

说到IOC,就不能不说DI。DI:即依赖注入,是IOC的实现手段。

二、使用Unity实现IOC

Unity是一个IoC容器,用来实现依赖注入(Dependency Injection,DI),减少耦合的,Unity出自于伟大的微软。

unity能够做什么呢,列举部分如下:

1.Unity支持简单对象创建,特别是分层对象结构和依赖,以简化程序代码。其包含一个编译那些可能存在依赖于其他对象的对象实例机制。
2.Unity支持必要的抽象,其允许开发者在运行时或配置去指定依赖关系同时可以简单的管理横切点(AOP)。
3.Unity增加了推迟到容器组件配置的灵活性。其同样支持一个容器层次的结构。
4.Unity拥有服务定位能力,对于一个程序在许多情况下重复使用组件来分离和集中功能是非常有用的。
5.Unity允许客户端储存或缓存容器。对于在ASP.NET Web applications中开发者将容器持久化于ASP.NET中的session或application中特别有效。
6.Unity拥有拦截能力,其允许开发者通过创建并执行handlers(在方法或属性被调用到达之前)来为已存在的组件增加一个函数,并再次为返回调用结果。
7.Unity可以从标准配置系统中读取配置信息,例如:XML文件,同时使用配置文件来配置容器。
8.Unity支持开发者实现自定义容器扩展,例如:你可以实现方法来允许额外的对象构造和容器特征,例如缓存。
9.Unity允许架构师和开发者在现代化的程序中更简单的实现通用设计模式。

什么情况下要使用unity呢?

1.所构建的系统依赖于健全的面向对象原则,但是大量不同的代码交织在一起而难以维护。
2.构建的对象和类需要依赖其他对象或类。
3.依赖于复杂的或需要抽象的对象。
4.希望利用构造函数、方法或属性的调用注入优势。
5.希望管理对象实例的生命周期。
6.希望能够在运行时管理并改变依赖关系。
7.希望在拦截方法或属性调用的时候生成一个策略链或管道处理容器来实现横切(AOP)任务。
8.希望在Web Application中的回发操作时能够缓存或持久化依赖关系。

1、程序中安装Unity

使用管理NuGet程序包来安装Unity,在项目上右键,选择管理NuGet程序包:

在搜索框里面输入Unity,点击右侧安装按钮进行安装:

出现以下信息表示安装成功:

2、使用Unity实现DI

先来看看最简单的Unity实现方式:

IUnityContainer container = new UnityContainer();//1、定义一个空容器
container.RegisterType<IDbInterface, DbMSSQL>();//2、注册类型,表示遇到IDbInterface的类型,创建DbMSSQL的实例
var db = container.Resolve<IDbInterface>();
Console.WriteLine(db.Insert());
Console.ReadKey();

结果:

从结果中可以看出,db是DbMSSQL类型的实例。

除了使用RegisterType注册类型以外,还可以注册一个实例,例如:

// 使用RegisterInstance注册IDbInterface的实例:new DbMSSQL()
container.RegisterInstance<IDbInterface>(new DbMSSQL());

3、三种注入方式

三种注入方式:构造函数注入、属性注入、方法注入。

3.1 定义IHeadphone接口,代码如下:

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

namespace DataBase.Interface
{
    public interface IHeadphone
    {

    }
}

3.2 定义IMicrophone接口,代码如下:

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

namespace DataBase.Interface
{
    public interface IMicrophone
    {

    }
}

3.3 定义IPower接口,代码如下:

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

namespace DataBase.Interface
{
    public interface IPower
    {

    }
}

3.4 定义IPhone接口,代码如下:

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

namespace DataBase.Interface
{
    public interface IPhone
    {
        void Call();
        IMicrophone iMicrophone { get; set; }
        IHeadphone iHeadphone { get; set; }
        IPower iPower { get; set; }
    }
}

3.5 分别实现上面定义的接口

IPhone接口的实现如下:

using DataBase.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity.Attributes;

namespace DataBase.MSSQL
{
    public class ApplePhone : IPhone
    {
        [Dependency]//属性注入
        public IMicrophone iMicrophone { get; set; }
        public IHeadphone iHeadphone { get; set; }
        public IPower iPower { get; set; }

        [InjectionConstructor]//构造函数注入
        public ApplePhone(IHeadphone headphone)
        {
            this.iHeadphone = headphone;
            Console.WriteLine("{0}带参数构造函数", this.GetType().Name);
        }

        public void Call()
        {
            Console.WriteLine("{0}打电话", this.GetType().Name); ;
        }

        [InjectionMethod]//方法注入
        public void Init1234(IPower power)
        {
            this.iPower = power;
        }
    }
}

IHeadphone接口的实现如下:

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

namespace DataBase.MSSQL
{
    public class Headphone : IHeadphone
    {
        public Headphone()
        {
            Console.WriteLine("Headphone 被构造");
        }
    }
}

IMicrophone接口的实现如下:

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

namespace DataBase.MSSQL
{
    public class Microphone : IMicrophone
    {
        public Microphone()
        {
            Console.WriteLine("Microphone 被构造");
        }
    }
}

IPower接口的实现如下:

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

namespace DataBase.MSSQL
{
    public class Power : IPower
    {
        public Power()
        {
            Console.WriteLine("Power 被构造");
        }
    }
}

控制台程序调用:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DataBase.Interface;
using DataBase.MSSQL;
using Unity;

namespace IOCConApp
{
    /// <summary>
    /// IOC():控制反转,把程序上层对下层的依赖,转移到第三方的容器来装配
    ///          是程序设计的目标,实现方式包含了依赖注入和依赖查找(.net里面只有依赖注入)
    /// DI:依赖注入,是IOC的实习方式。
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            #region MyRegion
            //// 常规做法,即程序的上端,依赖于下端,依赖于细节
            //DbMSSQL mssql = new DbMSSQL();

            //// 通过抽象来依赖
            //IDbInterface dbInterface = new DbMSSQL();

            //IUnityContainer container = new UnityContainer();//1、定义一个空容器
            //container.RegisterType<IDbInterface, DbMSSQL>();//2、注册类型,表示遇到IDbInterface的类型,创建DbMSSQL的实例
            //var db = container.Resolve<IDbInterface>();

            //// 使用RegisterInstance注册IDbInterface的实例:new DbMSSQL()
            //container.RegisterInstance<IDbInterface>(new DbMSSQL());
            //Console.WriteLine(db.Insert());
            #endregion

            IUnityContainer container = new UnityContainer();
            container.RegisterType<IPhone, ApplePhone>();
            container.RegisterType<IMicrophone, Microphone>();
            container.RegisterType<IHeadphone, Headphone>();
            container.RegisterType<IPower, Power>();

            IPhone phone = container.Resolve<IPhone>();

            Console.WriteLine($"phone.iHeadphone==null?  {phone.iHeadphone == null}");
            Console.WriteLine($"phone.iMicrophone==null? {phone.iMicrophone == null}");
            Console.WriteLine($"phone.iPower==null?      {phone.iPower == null}");

            Console.ReadKey();
        }
    }
}

输出结果:

从输出结果中可以看出三种注入方式的执行顺序:先执行构造函数注入,在执行属性注入,最后执行方法注入。

注意:默认情况下如果构造函数上面没有使用特性,那么默认找参数最多的构造函数执行注入。

4、一个接口多个实现进行注册

如果多个不同的实例实现同一个接口,这种情况该怎么注册呢?先来看看下面的代码:

IUnityContainer container = new UnityContainer();//1、定义一个空容器
container.RegisterType<IDbInterface, DbMSSQL>();//2、注册类型,表示遇到IDbInterface的类型,创建DbMSSQL的实例
container.RegisterType<IDbInterface, DbOracle>();//表示遇到IDbInterface的类型,创建DbMSSQL的实例
var db = container.Resolve<IDbInterface>();
Console.WriteLine(db.Insert());

运行结果:

从运行结果中可以看出,后面注册的类型会把前面注册的类型给覆盖掉,那么该如何解决呢?可以通过参数的方式来解决,代码如下:

IUnityContainer container = new UnityContainer();//1、定义一个空容器
container.RegisterType<IDbInterface, DbMSSQL>("sql");//2、注册类型,表示遇到IDbInterface的类型,创建DbMSSQL的实例
container.RegisterType<IDbInterface, DbOracle>("oracle");//表示遇到IDbInterface的类型,创建DbMSSQL的实例
var sql = container.Resolve<IDbInterface>("sql");
var oracle = container.Resolve<IDbInterface>("oracle");
Console.WriteLine(sql.Insert());
Console.WriteLine(oracle.Insert());

运行结果:

5、生命周期

生命周期及一个对象从创建到释放中间经过的时间。先看下面的代码:

IUnityContainer container = new UnityContainer();
container.RegisterType<IDbInterface, DbMSSQL>();
IDbInterface db1 = container.Resolve<IDbInterface>();
IDbInterface db2 = container.Resolve<IDbInterface>();
Console.WriteLine("HashCode:"+db1.GetHashCode().ToString());
Console.WriteLine("HashCode:" + db2.GetHashCode().ToString());
Console.WriteLine(object.ReferenceEquals(db1,db2));

结果:

表明db1和db2是两个不同的实例,即默认情况下生命周期是瞬时的,每次都是创建一个新的实例。

container.RegisterType<IDbInterface, DbMSSQL>(new TransientLifetimeManager());表示是瞬时生命周期,默认情况下即这种。

在看下面的代码:

IUnityContainer container = new UnityContainer();
container.RegisterType<IDbInterface, DbMSSQL>(new ContainerControlledLifetimeManager());
IDbInterface db1 = container.Resolve<IDbInterface>();
IDbInterface db2 = container.Resolve<IDbInterface>();
Console.WriteLine("HashCode:" + db1.GetHashCode().ToString());
Console.WriteLine("HashCode:" + db2.GetHashCode().ToString());
Console.WriteLine(object.ReferenceEquals(db1, db2));

结果:

上图的结果可以看出,db1和db2是同一个实例。

container.RegisterType(new ContainerControlledLifetimeManager())表示是容器单例,每次都是同一个实例。

6、使用配置文件实现

在上面的例子中,所有的例子都是一直在依赖于细节,那么怎么解决不依赖于细节呢?答案是只能使用配置文件,配置文件如下:

<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
  </configSections>
  <unity>
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/>
    <containers>
      <container name="testContainer">
        <!--逗号前面是接口类型的完全限定名:命名空间+接口名称,逗号后面是DLL文件的名称 name解决同一个接口不同实例问题-->
        <register type="DataBase.Interface.IDbInterface,DataBase.Interface" mapTo="DataBase.MSSQL.DbMSSQL, DataBase.MSSQL" name="sql"/>
        <register type="DataBase.Interface.IDbInterface,DataBase.Interface" mapTo="DataBase.Oracle.DbOracle, DataBase.Oracle" name="oracle"/>
      </container>
    </containers>
  </unity>
</configuration>

注意:这个一个单独的配置文件,要把属性里面的复制到输出目录改为始终复制,那么这个配置文件才会生成到Debug目录里面。

程序如下:

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\\Unity.Config");//找配置文件的路径
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
 UnityConfigurationSection section = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
IUnityContainer container = new UnityContainer();
section.Configure(container, "testContainer");
IDbInterface db = container.Resolve<IDbInterface>("sql");
 Console.WriteLine(db.Insert());

结果:

观察上面的代码,会发现,如果改成使用配置文件的方式实现的话,代码里面就不会依赖于细节了,只要一个接口类型。既然没有细节了,那么对项目进行如下的改造:把引用里面对细节的引用都去掉(即去掉DataBase.MSSQL和DataBase.Oracle),然后Debug文件夹里面没有这两个DLL了,但是这时需要把这两个DLL复制到Debug目录下面,否则程序运行的时候会找不到具体实现的类型。这样就意味着程序架构只依赖于接口。

引用里面只要对接口的引用了,没有对具体实现的引用。去掉了对细节的依赖。

注意:使用配置文件实现时,必须把接口的具体实现类复制到程序目录下面。

如果有额外添加了一种数据库,那么只需要修改配置文件,把新的实现类复制到程序目录下面即可实现程序的升级。

使用配置文件的时候,需要把UnityContainer容器定义为静态的,这样只需要读取一次配置文件即可。

到此这篇关于C#使用Unity实现IOC的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C#中Socket与Unity相结合示例代码

    前言 初步接触了Socket,现使其与Unity相结合,做成一个简单的客户端之间可以互相发送消息的一个Test.下面话不多说了,来一起看看详细的介绍吧. 方法如下: 首先,是服务端的代码. 创建一个连接池,用于存储客户端的数量. using System; using System.Net; using System.Net.Sockets; using System.Collections; using System.Collections.Generic; namespace Server

  • Unity C#打包AssetBundle与场景详解

    Unity2018已经把打包过程简化很多了 我们只需要关心两个API: 1.BuildPipline.BuildAssetBundles() 打包AssetBundle 2.BuildPipline.BuildPlayer() 打包场景 1.打包AssetBundle 先在资源的Inspector面板最下方 填写资源所属的AssetBundle名称和后缀(后缀可以不填) 再利用BuildPipeline.BuildAssetBundles()进行打包 2.打包Scene 利用BuildPipel

  • 关于Unity C# Mathf.Abs()取绝对值性能测试详解

    前言 之前有人提到过取绝对值时 直接写三目运算符比用Mathf.Abs()效率高 没觉得能高太多 今天测了一下 真是不测不知道 一测吓一跳 直接写三目运算符比Mathf.Abs()效率高2-3倍 这性能差距有点不太合理啊! 看下源码发现 很多Mathf的方法就是多封装了一层Math里的方法 把double型转成float型了 即便很简单得方法也没有重新实现 官方有点偷懒了 所以性能差距才会这么大 以后要求性能高的地方要注意 老老实实写一遍 能提升不少性能 测试代码: using UnityEng

  • 利用unity代码C#封装为dll的步骤分享

    前言 本文主要介绍了关于unity代码C#封装为dll的相关内容,分享出来供需要的朋友们学习,下面话不多说了,来一起学习学习吧. 方法如下 1 Visual studio软件打开后创建一个项目 2并选择类库类型 3编写简单的代码看看效果(发现会报错),主要是没有添加类库,以及using UnityEngine;引用空间 4添加类库,引用空间 发现依然会报错,这就需要添加应用库unityengine.dll,方法如下 找到安装unity目录下的UnityEngine.dll,添加后你就会发现,报红

  • C#在Unity游戏开发中进行多线程编程的方法

    在这之前,有很多人在质疑Unity支不支持多线程,事实上Unity是支持多线程的.而提到多线程就要提到Unity非常常用的协程,然而协程并非真正的多线程.协程其实是等某个操作完成之后再执行后面的代码,或者说是控制代码在特定的时机执行.而多线程在Unity渲染和复杂逻辑运算时可以高效的使用多核CPU,帮助程序可以更高效的运行.本篇主要介绍在Unity中如何使用多线程. 首先引入C#中使用多线程的类库 using System.Threading; 创建线程实例的四种方式 一.线程执行无参方法 构造

  • C#使用Protocol Buffer(ProtoBuf)进行Unity中的Socket通信

    首先来说一下本文中例子所要实现的功能: 基于ProtoBuf序列化对象 使用Socket实现时时通信 数据包的编码和解码 下面来看具体的步骤: 一.Unity中使用ProtoBuf 导入DLL到Unity中, 创建网络传输的模型类: using System; using ProtoBuf; //添加特性,表示可以被ProtoBuf工具序列化 [ProtoContract] public class NetModel { //添加特性,表示该字段可以被序列化,1可以理解为下标 [ProtoMem

  • Unity之Luaframework框架lua调用C#方法

    前言 最近,新来的同事写接口,需要知道lua怎么调用C#脚本,趁这个机会也给大家分享一下.道理我也不多少,直接上干货. 框架介绍 本项目采用luaframework+ugui,详情咨询度娘. 框架: 创建C#类 首先写个C#脚本,这个脚本里的方法是我们需要在lua中调用的,这里需要调用的方法命名为ShirlnDebug using System.Collections; using System.Collections.Generic; using UnityEngine; public cla

  • C#语言使用Unity实现剪刀石头布游戏

    本文实例为大家分享了C#语言使用Unity实现剪刀石头布游戏的具体代码,供大家参考,具体内容如下 游戏:剪刀石头布 实现功能: 1.电脑随机出牌(剪刀石头布) 2.玩家选择出牌(剪刀石头布) 3.玩家没有出牌时,电脑变幻牌面: 玩家出牌后,电脑出牌,并停止变幻牌面3秒,期间玩家无法选择出牌 4.玩家和电脑出牌后,电脑自动计分. using UnityEngine; using System.Collections; public class hw0310a : MonoBehaviour { /

  • C#编程中常见数据结构的比较(Unity3D游戏开发)

    一.前言 Unity3D是如今最火爆的游戏开发引擎,它可以让我们能轻松创建诸如三维视频游戏.建筑可视化.实时三维动画等类型的互动内容.它支持2D/3D游戏开发,据不完全统计,目前国内80%的手机游戏都是用Unity3D开发. 由于Unity3D在开发过程中使用最多的是C# 语言,所以就要合理的使用C#提供的一些数据结构是非常有必要的,合理的选择数据结构可以加快开发速度,提高游戏运行性能,不合理的使用数据结构则会导致游戏运行性能降低,加大开发复杂程度! 先通过表格看看常用的数据结构: C#常用数据

  • C#使用Unity实现IOC

    一.什么是IOC 学习IOC之前先来了解一个依赖导致原则(DIP),依赖导致原则是IOC的核心原理. 依赖导致:即上层模块不应该依赖于低层模块,二者应该通过抽象来依赖.依赖于抽象,而不是依赖于细节. 首先来看下面的例子: 1.定义一个接口,封装数据库的基本CRUD操作,接口定义如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threadin

  • ASP.NET MVC如何使用Unity实现Ioc详解

    为什么有这篇文章 最近在学ASP.NET MVC项目中使用Ioc,选用了Unity作为依赖注入的容器组件,在网上找了相关的文章简单实现了依赖注入,但想用文件配置的方式进行容器注入的注册,发现相关的文章实现的方式不适用,因为网上的文章大多是使用Unity 4.0.1的版本,而目前最新的Unity版本是5.8.6,使用配置进行容器注入的代码已然不同. Ioc和Unity IOC(Inversion of Control),即"控制反转",是一种设计思想.有了IoC后,把创建和查找依赖对象的

  • .NET Unity IOC框架使用实例详解

    .NET Unity IOC框架的使用实例,具体内容如下 1.IOC简介 IOC(Inversion of Control), 控制反转 DI (Dependency Injection),依赖注入 IOC的基本概念是:不创建对象,但是描述创建它们的方式.在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务.容器负责将这些联系在一起. 2.Unity引入 3.创建单例模式容器类 using Microsoft.Practices.Unity; using Microsoft

  • 基于Unity容器中的对象生存期管理分析

    IoC容器的对象生存期管理 如果你一直在使用IoC容器,你可能已经使用过了一些对象生存期管理模型(Object Lifetime Management).通过对对象生存期的管理,将使对象的复用成为可能.同时其使容器可以控制如何创建和管理对象实例. Unity提供的对象生存期管理模型是通过从抽象类LifetimeManager的派生类来完成.Unity将为每个类型的注册创建生存期管理器.每当UnityContainer需要创建一个新的对象实例时,将首先检测该对象类型的生存期管理器,是否已有一个对象

  • Golang轻量级IoC容器安装使用示例

    目录 1. iocgo简介 2. iocgo如何使用 2.1 iocgo包的安装 2.2 使用示例与说明 2.2.1 最简单的例子: 2.22. Register 的选项 2.2.3. 注册实例 2.2.4. 获得实例 2.2.5. 结构体参数和字段填充 2.2.6. 函数调用 2.3 参考: 3. 总结 1. iocgo简介 习惯于Java或者C#开发的人应该对控制反转与依赖注入应该再熟悉不过了.在Java平台有鼎鼎大名的Spring框架,在C#平台有Autofac,Unity,Windsor

  • Unity编辑器下重启的方法

    Unity编辑器下重启的方法 我们项目AssetBundle打包走的是全自动化流程,打包之前要进行各种资源检测,如果检测顺利通过,则进入打包,否则提示错误资源名称及路径,打包中断!有时候即使资源检测通过也会打包崩溃,初步断定是Unity的内存爆了,因为Unity在编辑器下打开工程中的资源不会释放掉,所以内存一直在占用,打包时要进行一系列资源依赖分析,我们也知道,如果资源量非常大时候,Unity要保存资源依赖的堆栈,所以会有内存崩掉的风险,所以我就想着,打包之前重启下Unity,让Unity释放掉

  • 利用Spring IOC技术实现用户登录验证机制

    利用 Spring IOC 技术实现用户登录的验证机制,对用户进行登录验证. 首先利用 Spring 的自动装配模式将 User 对象注入到控制器中,然后将用户输入的用户名和密码与系统中限定的合法用户的用户名和密码进行匹配. 当用户名与密码匹配成功时,跳转到登录成功页面:当用户名与密码不匹配时,跳转到登录失败的页面. 1.创建 User 对象,定义用户名和密码属性,代码如下: package com.importnew; public class User { private String us

  • Spring boot实现一个简单的ioc(1)

    前言 跳过废话,直接看正文 之前参与开发的几个spring的项目,用的版本都3.x, 最近忽然发现spring 5 都快上线了,于是赶紧去关注了下spring的最新动态.发现了spring-boot这个好东西(终于可以从各种错综复杂的xml配置文件中解放出来了!). 在学习了目前最新的1.5.2.RELEASE版spring-boot官方文档之后,我决定仿照spring-boot的项目结构以及部分注解,写一个简单的ioc容器,一方面为了加深自己对ioc的理解,另一方面也为了以后在开发一些个人项目

  • Spring boot实现一个简单的ioc(2)

    前言 跳过废话,直接看正文 仿照spring-boot的项目结构以及部分注解,写一个简单的ioc容器. 测试代码完成后,便正式开始这个ioc容器的开发工作. 正文 项目结构 实际上三四个类完全能搞定这个简单的ioc容器,但是出于可扩展性的考虑,还是写了不少的类. 因篇幅限制,接下来只将几个最重要的类的代码贴出来并加以说明,完整的代码请直接参考https://github.com/clayandgithub/simple-ioc. SimpleAutowired 代码 import java.la

随机推荐