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 ...
随机推荐
- 【Linux】Linux简介
思维导图 什么是Linux? Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU的操作系统. Linux能运行主要的UNIX工 ...
- Oracle存储过程向Hadoop迁移中的问题及方案
本文记录Oracle存储过程向Hadoop迁移中遇到的问题及响应的解决办法,作为初学者,文中内容有不妥之处欢迎指正, 1.不支持IN中的子查询,Solution,使用INNER JOIN将子查询操作添 ...
- window.open 打开全屏窗口
window.open新打开页面为全屏状态,各个浏览器情况不一致. window.open 弹出新窗口的命令: 'page.html' 弹出窗口的文件名: 'newwindow ...
- BZOJ.2616.SPOJ PERIODNI(笛卡尔树 树形DP)
BZOJ SPOJ 直观的想法是构建笛卡尔树(每次取最小值位置划分到两边),在树上DP,这样两个儿子的子树是互不影响的. 令\(f[i][j]\)表示第\(i\)个节点,放了\(j\)个车的方案数. ...
- 潭州课堂25班:Ph201805201 tornado 项目 第九课 深入应用 WebSockets(课堂笔记)
tornado 相关说明 在 handler 中创建一个 chat.py 文件,用来处理聊天室 在 templates 模板文件夹下创建 room.html 文件,是个聊天室 做好服务器的准备
- 自定义MVC实现登录案例
MVC框架: MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界面显示分离 ...
- Sting、StringBuffer、StringBuilder
(1)String是字符串常量,一旦创建之后不可更改:StringBuffer和StringBuilder是字符串变量,可以更改.String的不可变,所以适合作为Map的键. (2)StringBu ...
- Spring 使用 feign时设置header信息
最近使用 SpringBoot 项目,把一些 http 请求转为 使用 feign方式.但是遇到一个问题:个别请求是要设置header的. 于是,查看官方文档和博客,大致推荐两种方式.也可能是我没看明 ...
- Solve Error: node postinstall sh: node: command not found
When install the yeoman using the following command: npm install -g yo You might have the following ...
- AJAX-wamp安装的“橙色”问题
安装wamp可能会出现的问题 ##1 正常安装wamp后,打开wamp可以在右下角看到一个图片,绿色即正常,红色或者橙色即意味着Apache+Mysql/MariaDB+Perl/PHP/Python ...