简介:

   控制反转:我们向IOC容器发出获取一个对象实例的一个请求,IOC容器便把这个对象实例“注入”到我们的手中,在这个过程中你不是一个控制者而是一个请求者,依赖于容器提供给你的资源,控制权落到了容器身上。这个过程就是控制反转。 

    依赖注入:我们向容器发出请求以后,获得这个对象实例的过程就叫依赖注入。

   关于Ioc的框架有很多,比如astle Windsor、Unity、Spring.NET、StructureMap,我们这边使用微软提供的Unity做示例,你可以使用 Nuget 添加 Unity ,也可以引用Microsoft.Practices.Unity.dll和Microsoft.Practices.Unity.Configuration.dll,下面我们就一步一步的学习下 Unity依赖注入 的详细使用。

一、使用 Nuget 添加 Unity

二、实现构造注入

添加一个接口和一个实现类,通过Main()方法调用测试。

    /// <summary>
/// 显示信息
/// </summary>
public interface IUserDao
{
void Display(string mes);
} class UserImpl : IUserService
{
public IUserDao IUserDao;
//构造函数设置值
public UserImpl(IUserDao UserDao)
{
IUserDao = UserDao;
}
/// <summary>
/// 显示信息
/// </summary>
/// <param name="mes"></param>
public void Display(string mes)
{
IUserDao.Display(mes);
}
}
 
    /// <summary>
/// 显示信息
/// </summary>
public interface IUserDao
{
void Display(string mes);
} public class UserDaoImpl : IUserDao
{
public void Display(string mes)
{
Console.WriteLine(mes);
}
}
 
class Program
{
public IUserService IUserService { get; set; } public static void Main(string[] args)
{
//创建容器
UnityContainer container = new UnityContainer();
//注册依赖对象
container.RegisterType<IUserService, UserImpl>();
container.RegisterType<IUserDao, UserDaoImpl>();
//返回调用者
IUserService IUser = container.Resolve<UserImpl>();
//执行
IUser.Display("asb");
Console.ReadLine();
}
}

点击运行,成功输出。

构造器注入
构造器注入(Constructor Injection):IoC容器会智能地选择选择和调用适合的构造函数以创建依赖的对象。
如果被选择的构造函数具有相应的参数,IoC容器在调用构造函数之前解析注册的依赖关系并自行获得相应参数对象。
RegisterType:可以看做是自来水厂决定用什么作为水源,可以是水库或是地下水,我只要“注册”开关一下就行了。
Resolve:可以看做是自来水厂要输送水的对象,可以是农村或是城市,我只要“控制”输出就行了。

三、属性注入

属性注入(Property Injection),就是通过 set 设值对对象进行设值,只需要在调用对象的上面加上 [Dependency] 标记即可。当依赖对象被容器初始化以后,会自动对该对象设值。

class UserImpl : IUserService
{
//只需要在对象成员前面加上[Dependency],
//就是把构造函数去掉,成员对象上面加[Dependency]注入
[Dependency]
public IUserDao IUserDao { get; set; } //public UserImpl(IUserDao UserDao)
//{
// IUserDao = UserDao;
//}
/// <summary>
/// 显示信息
/// </summary>
/// <param name="mes"></param>
public void Display(string mes)
{
IUserDao.Display(mes);
}
}

点击运行,实现的结果是一样的。

配置文件注册:

  其实使用上面 RegisterType 方法进行注册,每次添加和删除一个注册都需要去修改代码和重新编译,这样不符合“高内聚、低耦合”的编程思想,所以我们可以采用配置文件的方式去注册,这样每次添加和修改注册就不需要去修改代码和重新发布了。配置文件注册用 UnityConfigurationSection 的 Configure加载配置文件注册。

代码(如果是控制台程序,配置写在App.config,如果是Web程序,就写在 Web.config):

<?xml version="1.0" encoding="utf-8" ?>
<configuration> <configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
Microsoft.Practices.Unity.Configuration" />
</configSections>
<unity xmlns="http://schemas.microsoft.com/practces/2010/unity">
<containers>
<!--MyContainer为自定义名称 只需要和调用时名称保持一致即可-->
<container name="MyContainer">
<!--type为对象的名称,mapTo为注入对象的名称 写法为用逗号隔开两部分,一是类的全部,包括命名空间,二是程序集名称-->
<register type="ThreadDemo.Bll.IUserBll,ThreadDemo" mapTo="ThreadDemo.Bll.impl.UserBll,ThreadDemo">
<lifetime type="singleton" />
</register>
<register type="ThreadDemo.Dal.IUserDal,ThreadDemo" mapTo="ThreadDemo.Dal.impl.UserDal,ThreadDemo"/>
</container>
</containers>
</unity>
<!--startup必须放在<configSections>节点下面,否则报错-->
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>
 
class Program
{
public IUserBll UserBll { get; set; } public static void Main(string[] args)
{
//创建容器
//UnityContainer container = new UnityContainer();
//注册依赖对象
//container.RegisterType<IUserService, UserImpl>();
//container.RegisterType<IUserDao, UserDaoImpl>();
//返回调用者
//IUserService IUser = container.Resolve<UserImpl>(); //创建容器
UnityContainer container = new UnityContainer();
UnityConfigurationSection config = (UnityConfigurationSection)ConfigurationManager.GetSection(UnityConfigurationSection.SectionName);
//加载到容器
config.Configure(container, "MyContainer"); //返回调用者
IUserBll IUser = container.Resolve<IUserBll>();
//执行
IUser.Display("abc");
Console.ReadLine();
}
}

四、方法注入

  方法注入和构造注入差不多,只不过把构造函数变成了一个普通的方法,在方法前面加  [InjectionMethod]  属性。

namespace ThreadDemo.Bll.impl
{
public class UserBll : IUserBll
{
public IUserDal IDal; /// <summary>
/// 方法注入-加[InjectionMethod]属性
/// </summary>
/// <param name="IUserDal"></param>
[InjectionMethod]
public void SetInjection(IUserDal IUserDal)
{
IDal = IUserDal;
} /// <summary>
/// 显示信息
/// </summary>
/// <param name="mes"></param>
public void Display(string mes)
{
IDal.Display(mes);
}
}
}

这几种方法运行结果都是一样的。

五、Unity.MVC在Web中的应用

下面的例子是在Unity在Web项目中的使用:

1、安装Unity.MVC

2、在目录下会生成一个 BootStrapper.cs  的类文件,打开进行 编辑(如果没有生成,自己创建,名称随意)。

namespace ShowWeatherWebUI
{
public class BootStrapper
{
/// <summary>
/// 获取容器-注册依赖关系
/// </summary>
/// <returns></returns>
public static IUnityContainer Initialise()
{
var container = BuildUnityContainer(); DependencyResolver.SetResolver(new UnityDependencyResolver(container)); return container;
} /// <summary>
/// 加载容器
/// </summary>
/// <returns></returns>
private static IUnityContainer BuildUnityContainer()
{
var container = new UnityContainer(); RegisterTypes(container); return container;
} /// <summary>
/// 实施依赖注入
/// </summary>
/// <param name="container"></param>
private static void RegisterTypes(UnityContainer container)
{
//依赖关系可以选择代码形式,也可以用配置文件的形式
//UnityConfigurationSection config = (UnityConfigurationSection)ConfigurationManager.GetSection(UnityConfigurationSection.SectionName);
//加载到容器
//config.Configure(container, "MyContainer"); container.RegisterType<IUerBll, UerBll>();
container.RegisterType<IUserDal, UserDal>();
}
}
}

3、在 Global.asax 文件中添加 BootStrapper.Initialise() 的方法。

  因为Global.asax是应用程序启动的时候会执行,所以会去加载容器

public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
//加载容器-注册依赖
BootStrapper.Initialise();
}
}

4、在Controller里调用,

在每个调用的接口添加 [Dependency] 属性即可,也就是属性输入,也可以采用构造函数注入和方法注入。

 public class HomeController : Controller
{
[Dependency]
public IUerBll bll { get; set; } public ActionResult Index()
{
bll.Display("asd");
return View();
}
}

代码下载

C# Unity依赖注入的更多相关文章

  1. Unity 依赖注入之二

    1. 构造子注入 1.1 构造子注入初级代码 container.RegisterType<IMyWork, MyWork>(new InjectionConstructor(new Bo ...

  2. Unity依赖注入使用详解

    写在前面 构造器注入 Dependency属性注入 InjectionMethod方法注入 非泛型注入 标识键 ContainerControlledLifetimeManager单例 Unity注册 ...

  3. WPF PRISM开发入门二(Unity依赖注入容器使用)

    这篇博客将通过一个控制台程序简单了解下PRISM下Unity依赖注入容器的使用.我已经创建了一个例子,通过一个控制台程序进行加减乘除运算,项目当中将输入输出等都用接口封装后,结构如下: 当前代码可以点 ...

  4. Unity 依赖注入

    关于Ioc的框架有很多,比如astle Windsor.Unity.Spring.NET.StructureMap,我们这边使用微软提供的Unity做示例,你可以使用Nuget添加Unity,也可以引 ...

  5. c# Unity依赖注入WebService

    1.IOC与DI简介 IOC全称是Inversion Of Control(控制反转),不是一种技术,只是一种思想,一个重要的面相对象编程的法则,它能知道我们如何设计出松耦合,更优良的程序.传统应用程 ...

  6. 使用Microsoft.Practices.Unity 依赖注入

    Unity是微软Patterns & Practices团队所开发的一个轻量级的,并且可扩展的依赖注入(Dependency Injection)容器,它支持常用的三种依赖注入方式:构造器注入 ...

  7. 使用Microsoft.Practices.Unity 依赖注入 转载https://www.cnblogs.com/slardar1978/p/4205394.html

    Unity是微软Patterns & Practices团队所开发的一个轻量级的,并且可扩展的依赖注入(Dependency Injection)容器,它支持常用的三种依赖注入方式:构造器注入 ...

  8. ASP.NET MVC5+EF6+EasyUI 后台管理系统(6)-Unity 依赖注入

    系列目录 前言 为了符合后面更新后的重构系统,文章于2016-11-1日重写 本节重构一下代码,采用IOC控制反转,也就是依赖注入 您可以访问http://unity.codeplex.com/rel ...

  9. Unity 依赖注入知识点

    三种依赖注入方法,构造器注入.属性注入.方法注入 可以配置Config文件,来实现不用修改代码.需要先将接口与实体关联,然后使用时会自动加载对应实体. namespace WeChatConsole ...

随机推荐

  1. 利用反射获取数据列+emit生成属性+单例模式

    1:IDictionary<string,string > 可以存储数据,将拼接的sql可以存储到这里下次可以使用 定义自定义属性表和列 typeof(T).GetCustomAttrib ...

  2. WEB测试重点

    1.功能测试:所实现的功能是否和需求一致:2.界面测试:界面是否美观,风格是否一致,文字内容是否正确:3.链接测试:打开链接速度是否合理:是否链接到正确的页面:是否有空白页面:4.性能测试:系统能支持 ...

  3. 我是如何用redis做实时订阅推送的

    前阵子开发了公司领劵中心的项目,这个项目是以redis作为关键技术落地的.       先说一下领劵中心的项目吧,这个项目就类似京东app的领劵中心,当然图是截取京东的,公司的就不截了...   其中 ...

  4. linux 添加ssh和开启ssh服务apt管理的ubuntu

    是在ubuntu下出现的需求 现笔记记录 apt-get  update 更新源命令 apt-get  install  openssh-server 安装ssh服务 容易出现无法定位软件包.出现此问 ...

  5. C#-导入Excel 内容到 DataTable中

    C#-导入Excel 内容到 DataTable中 直接传入文件路径,支持所有Excel格式. 缺点:如果数据量庞大会很占内存. public static DataTable ImportExcel ...

  6. BZOJ4665: 小w的喜糖 DP

    对于这道题,首先每个人的位置并不影响结果 所以我们可以将相同颜色糖果的人放在一块处理 设 $f_{i,j}$ 表示处理到第 $i$ 种糖果至少有 $j$ 人的糖果和原先的类型相同 枚举当前种类中不满足 ...

  7. silverlight 调试问题

    web端调用方式是:<param name="source" value="/ClientBin/Chns.Web.RoomChart.xap?v=012" ...

  8. page0902未完成

    /** * @author:(LiberHome) * @date:Created in 2019/3/1 23:14 * @description: * @version:$ */ import j ...

  9. js 第三期 小肩膀 第一段

    var 时间戳 = new.Date().getTime();//系统引擎 var 时间戳 = Date.now(); //V8引擎 数据类型 false =  underfuned =null = ...

  10. es7 async/await使用

    先创建一个promise对象,里面执行一个异步函数 function fetchUser() { return new Promise((resolve, reject) => { fetch( ...