C# Unity依赖注入
简介:
控制反转:我们向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依赖注入的更多相关文章
- Unity 依赖注入之二
1. 构造子注入 1.1 构造子注入初级代码 container.RegisterType<IMyWork, MyWork>(new InjectionConstructor(new Bo ...
- Unity依赖注入使用详解
写在前面 构造器注入 Dependency属性注入 InjectionMethod方法注入 非泛型注入 标识键 ContainerControlledLifetimeManager单例 Unity注册 ...
- WPF PRISM开发入门二(Unity依赖注入容器使用)
这篇博客将通过一个控制台程序简单了解下PRISM下Unity依赖注入容器的使用.我已经创建了一个例子,通过一个控制台程序进行加减乘除运算,项目当中将输入输出等都用接口封装后,结构如下: 当前代码可以点 ...
- Unity 依赖注入
关于Ioc的框架有很多,比如astle Windsor.Unity.Spring.NET.StructureMap,我们这边使用微软提供的Unity做示例,你可以使用Nuget添加Unity,也可以引 ...
- c# Unity依赖注入WebService
1.IOC与DI简介 IOC全称是Inversion Of Control(控制反转),不是一种技术,只是一种思想,一个重要的面相对象编程的法则,它能知道我们如何设计出松耦合,更优良的程序.传统应用程 ...
- 使用Microsoft.Practices.Unity 依赖注入
Unity是微软Patterns & Practices团队所开发的一个轻量级的,并且可扩展的依赖注入(Dependency Injection)容器,它支持常用的三种依赖注入方式:构造器注入 ...
- 使用Microsoft.Practices.Unity 依赖注入 转载https://www.cnblogs.com/slardar1978/p/4205394.html
Unity是微软Patterns & Practices团队所开发的一个轻量级的,并且可扩展的依赖注入(Dependency Injection)容器,它支持常用的三种依赖注入方式:构造器注入 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(6)-Unity 依赖注入
系列目录 前言 为了符合后面更新后的重构系统,文章于2016-11-1日重写 本节重构一下代码,采用IOC控制反转,也就是依赖注入 您可以访问http://unity.codeplex.com/rel ...
- Unity 依赖注入知识点
三种依赖注入方法,构造器注入.属性注入.方法注入 可以配置Config文件,来实现不用修改代码.需要先将接口与实体关联,然后使用时会自动加载对应实体. namespace WeChatConsole ...
随机推荐
- 20172328 2018-2019《Java软件结构与数据结构》第四周学习总结
20172328 2018-2019<Java软件结构与数据结构>第四周学习总结 概述 Generalization 本周学习了第六章·列表,主要让我们认识列表以及分析各种列表实现. 教材 ...
- webpack打包样式代码去重
一.问题描述 控制台审查样式,同一个样式被导入很多遍,每调用一次@import "common.less";打包时都会多出一份类似的样式代码. 二.问题分析 补上... 三.解决方 ...
- NOIP2017 d1t2 时间复杂度
题目传送门:洛谷P3952 大模拟不解释 #include<iostream> #include<cstdio> #include<cmath> #include& ...
- c#关键字和常用类型表快查
类型 字节 取值范围 说明 bool 1 true/false/null 布尔类型 char 2 0x0000~0xffff Unicode 16 位字符 byte 1 0~255 无符号的 8 位整 ...
- Idea快捷键和使用技巧【未完】
参考1:点击跳转 参考2:点击跳转2 整合后的如下所示:
- CentOS启动docker1.13失败(Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.)
一.启动失败 1.启动docker [root@localhost ~]# systemctl start docker Job for docker.service failed because t ...
- as项目找不到id
是app目录下一个iml文件的问题,从备份恢复就好了
- npm 安装 chromedriver 失败的解决办法
https://segmentfault.com/a/1190000008310875 npm install chromedriver --chromedriver_cdnurl=http://cd ...
- qmake: could not exec '/usr/lib/x86_64-linux-gnu/qt4/bin/qmake': No such file or directory
执行 qmake -v 出现错误:qmake: could not exec ‘/usr/lib/x86_64-linux-gnu/qt4/bin/qmake’: No such file or di ...
- Go笔记
#Go在win下安装 1. https://golang.google.cn/dl/下载 amd64 版本的zip包 2. 解压后将bin目录添加入path 3. go version可显示版本信息