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 ...
随机推荐
- python实现Hbase
1. 下载thrift 作用:翻译python语言为hbase语言的工具 2. 运行时先启动hbase 再启动thrift,最后在pycharm中通过happybase包连接hbase 在hbase目 ...
- Hierarchical clustering:利用层次聚类算法来把100张图片自动分成红绿蓝三种色调—Jaosn niu
#!/usr/bin/python # coding:utf-8 from PIL import Image, ImageDraw from HierarchicalClustering import ...
- 写给Android开发者的Kotlin入门
写给Android开发者的Kotlin入门 转 https://www.jianshu.com/p/bb53cba6c8f4 Google在今年的IO大会上宣布,将Android开发的官方语言更换为K ...
- docker环境中安装node、pm2,映射项目文件守护程序
1.docker安装完成后,获取对应版本,可自定义node版本,默认为最新版本. git pull node:<version> 2.编写Dockerfile,在文件中添加安装pm2命令. ...
- zepto中的scrollTo
//zepto没有scrollTo动画,这里扩展了一个scrollTo函数 $.fn.scrollTo = function(options) { var defaults = { scrollTop ...
- Django——图书管理系统
基于Django的图书管理系统 1.主体功能 1.列出图书列表.出版社列表.作者列表 2.点击作者,会列出其出版的图书列表 3.点击出版社,会列出旗下图书列表 4.可以创建.修改.删除 图书.作者.出 ...
- 24 GISer必备知识(一) 坐标系
对于经常使用ArcMap的童鞋,肯定用过属性表中的计算几何的功能,但是有时候会提示面积计算与长度计算禁用 但是选择的明明是 Xian 1980坐标系,这是为什么呢?下面就来讲一讲这些个经常让人“头大” ...
- java学习之路--I/O流
java基础学习总结——流 一.JAVA流式输入/输出原理
- logback使用注意点1
logback中配置了springProfile(策略),因此在properties中只需要配置如下即可logging.config=./config/logback.xml //logback配置文 ...
- 深度好文 | 在阿里做了5年技术Leader,我总结出了这些套路!
导读:阿里巴巴高级技术专家云狄将为大家从管理的角度分享技术TL的核心职责,这其中包括团队建设.团队管理.团队文化.沟通与辅导.招聘与解雇等,希望与大家共同探讨.交流. 背景 互联网公司的技术团队管理通 ...