[Solution] DI原理解析及Castle、Unity框架使用
本节目录
DI介绍
控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题.
依赖注入(Dependency Injection,英文缩写为DI)是一种设计模式.
其实本质都是指同一件事,强调的内容不一样.IoC强调容器的作用,DI强调注入的作用.
通常IoC和DI可以理解为一个意思,只是指的对象不同.
DI基本原理
DI本质上是通过容器来反射创建实例.
1个简单的类
class Person
{
public void Say()
{
Console.WriteLine("Person's say method is Called");
}
}
反射代码(className:类的全限定名)
private static object CreateInstance(Assembly assembly, string className)
{
var type = assembly.GetType(className);
return type != null ? Activator.CreateInstance(type) : null;
}
执行(XX为命名空间)
static void Main(string[] args)
{
var obj = CreateInstance(Assembly.GetExecutingAssembly(), "XX.Person");
var person = obj as Person;
if (person != null)
{
person.Say();
}
Console.ReadKey();
}
在上面能看到1个问题,一般情况下.既然使用DI,就不知道具体的注入对象.所以强调面向接口编程.
所以实际上一般先定义接口,再通过DI容器创建对象.
interface IPerson
{
void Say();
}
class Person : IPerson
{
public void Say()
{
Console.WriteLine("Person's say method is Called");
}
}
执行
static void Main(string[] args)
{
var obj = CreateInstance(Assembly.GetExecutingAssembly(), "Demo.Person");
var person = obj as IPerson;
if (person != null)
{
person.Say();
}
Console.ReadKey();
}
DI框架
DI框架流行的有Castle Windsor,Unity...(Autofac Spring.Net已经聊过,不再演示)
在DI框架中,一般需要将对象注册到容器中,然后从容器解析出来.
Castle
Install-Package Castle.Windsor
待注入类
interface ITransient
{ } interface IPerson
{
void Say();
}
class Person : IPerson, ITransient
{
public void Say()
{
Console.WriteLine("Person's say method is Called");
}
}
注册解析方式一
static void Main(string[] args)
{
using (var container = new WindsorContainer())
{
container.Register(Component.For<Person, IPerson>());
var person = container.Resolve<IPerson>();
person.Say();
}
Console.ReadKey();
}
注册解析方式二
public class AssmInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly() //选择Assembly
.IncludeNonPublicTypes() //约束Type
.BasedOn<ITransient>() //约束Type
.WithService.DefaultInterfaces() //匹配类型
.LifestyleTransient()); //注册生命周期
}
}
static void Main(string[] args)
{
using (var container = new WindsorContainer())
{
container.Install(new AssmInstaller());
var person = container.Resolve<IPerson>();
person.Say();
}
Console.ReadKey();
}
构造函数注入
class Task : ITransient
{
public IPerson Person { get; set; }
public Task(IPerson person)
{
Person = person;
Person.Say();
}
}
static void Main(string[] args)
{
using (var container = new WindsorContainer())
{
container.Install(new AssmInstaller());
container.Resolve<Task>();
}
Console.ReadKey();
}
属性注入
class Task : ITransient
{
public IPerson Person { get; set; }
public Task()
{
}
public void Say()
{
Person.Say();
}
}
static void Main(string[] args)
{
using (var container = new WindsorContainer())
{
container.Install(new AssmInstaller());
container.Resolve<Task>().Say();
}
Console.ReadKey();
}
MVC集成
Install-Package Castle.Windsor.Mvc
Application_Start注册
protected void Application_Start()
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
var container = new WindsorContainer()
.Install(FromAssembly.This());
var controllerFactory = new WindsorControllerFactory(container.Kernel);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
}
Installer注册
public class AssmInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly()
.IncludeNonPublicTypes()
.BasedOn<ITransient>()
.WithService.DefaultInterfaces()
.LifestyleTransient());
container.Register(Classes.FromThisAssembly()
.BasedOn<Controller>()
.LifestyleTransient()
);
}
}
这样Castle Windsor就能接管解析Controller了.
Unity
Install-Package Unity
待注入类
public interface IPerson
{
void Say();
}
public class Person : IPerson
{
public void Say()
{
Console.WriteLine("Person's say method is Called");
}
}
注册解析一
static void Main(string[] args)
{
using (var container = new UnityContainer())
{
container.RegisterType<IPerson, Person>(new TransientLifetimeManager());
var person = container.Resolve<IPerson>();
person.Say();
}
Console.ReadKey();
}
注册解析二
static void Main(string[] args)
{
using (var container = new UnityContainer())
{
container.RegisterInstance<IPerson>(new Person());
var person = container.Resolve<IPerson>();
person.Say();
}
Console.ReadKey();
}
构造函数注入
class Task : ITask
{
public IPerson Person { get; set; }
public Task(IPerson person)
{
Person = person;
Person.Say();
}
} public interface ITask
{ }
static void Main(string[] args)
{
using (var container = new UnityContainer())
{
container.RegisterInstance<IPerson>(new Person());
container.RegisterType<ITask, Task>();
container.Resolve<ITask>();
}
Console.ReadKey();
}
属性注入
class Task : ITask
{
[Dependency]
public IPerson Person { get; set; }
public Task(IPerson person)
{
Person = person;
}
public void Say()
{
Person.Say();
}
}
static void Main(string[] args)
{
using (var container = new UnityContainer())
{
container.RegisterInstance<IPerson>(new Person());
container.RegisterType<ITask, Task>();
var task = container.Resolve<ITask>();
task.Say();
}
Console.ReadKey();
}
MVC集成
Install-Package Unity.Mvc
Application_Start注册
protected void Application_Start()
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
var container = new UnityContainer();
container.RegisterType<IPerson, Person>();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
这样Unity就接管了Controller的创建
[Solution] DI原理解析及Castle、Unity框架使用的更多相关文章
- [Solution] AOP原理解析及Castle、Autofac、Unity框架使用
本节目录: AOP介绍 AOP基本原理 AOP框架 Castle Core Castle Windsor Autofac Unity AOP介绍 面向切面编程(Aspect Oriented Prog ...
- AOP原理解析及Castle、Autofac、Unity框架使用
转自:https://www.cnblogs.com/neverc/p/5241466.html AOP介绍 面向切面编程(Aspect Oriented Programming,英文缩写为AOP), ...
- DI 原理解析 并实现一个简易版 DI 容器
本文基于自身理解进行输出,目的在于交流学习,如有不对,还望各位看官指出. DI DI-Dependency Injection,即"依赖注入":对象之间依赖关系由容器在运行期决定, ...
- [置顶]
滴滴插件化框架VirtualAPK原理解析(一)之插件Activity管理
上周末,滴滴与360都开源了各自的插件化框架,VirtualAPK与RePlugin,作为一个插件化方面的狂热研究者,在周末就迫不及待的下载了Virtualapk框架来进行研究,本篇博客带来的是Vir ...
- ABP中动态WebAPI原理解析
ABP中动态WebAPI原理解析 动态WebAPI应该算是ABP中最Magic的功能之一了吧.开发人员无须定义继承自ApiController的类,只须重用Application Service中的类 ...
- Spring IOC设计原理解析:本文乃学习整理参考而来
Spring IOC设计原理解析:本文乃学习整理参考而来 一. 什么是Ioc/DI? 二. Spring IOC体系结构 (1) BeanFactory (2) BeanDefinition 三. I ...
- Web APi之过滤器创建过程原理解析【一】(十)
前言 Web API的简单流程就是从请求到执行到Action并最终作出响应,但是在这个过程有一把[筛子],那就是过滤器Filter,在从请求到Action这整个流程中使用Filter来进行相应的处理从 ...
- JavaScript 模板引擎实现原理解析
1.入门实例 首先我们来看一个简单模板: <script type="template" id="template"> <h2> < ...
- Request 接收参数乱码原理解析二:浏览器端编码原理
上一篇<Request 接收参数乱码原理解析一:服务器端解码原理>,分析了服务器端解码的过程,那么浏览器是根据什么编码的呢? 1. 浏览器解码 浏览器根据服务器页面响应Header中的“C ...
随机推荐
- windows批处理
1.日期作为变量当做文件名的一部分. C:\Documents and Settings\Simon>echo %date%2008-09-09 星期二 C:\Documents and Set ...
- 1、Orchard商城开发——开发需求
需要开发的功能: 1.商品详情,可添加商品属性,如颜色,尺寸等. 2.商品类别,可显示该类别下的所有商品,可按品牌.颜色.尺寸等检索,并可按价格.销量等排序游览. 3.商品游览记录,收藏商品,加入购物 ...
- Scala 深入浅出实战经典 第77讲:模式匹配下的提取器动手构造实战
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- 用etckeeper来解救运维工程师
对于运维工程师来讲,etc环境是一个痛点,各种配置,各种修改,某些软件的配置关联因素过多的话,那就更加痛苦了,改完发现不对再想改回去都千难万难, 现在有一个好的解决方案,那就是用etckeeper,绝 ...
- linux red hat 安装svn
安装步骤如下: 1.yum install subversion 2.输入rpm -ql subversion查看安装位置,如下图: 我们知道svn在bin目录下生成了几个二进制文件. 输入 ...
- Linux 求文件交集 差集等
使用comm命令 假设两个文件FILE1和FILE2用集合A和B表示,FILE1内容如下: a b c e d a FILE2内容如下: c d a c 基本上有两个方法,一个是comm命令,一个是g ...
- Updating Protobuf and GRPC in Golang
转自: http://russmatney.com/techsposure/update-protobuf-golang-grpc/ TL;DR: When protobuf updates, all ...
- BpBinder 转换为 BpCameraService 流程
interface_cast<ICameraService>(binder) : 其中binder 为IBinder类型,实际为BpBinder interface_cast 定义在IIn ...
- Hibernate一些防止SQL注入的方式
Hibernate在操作数据库的时候,有以下几种方法来防止SQL注入,大家可以一起学习一下. 1.对参数名称进行绑定: Query query=session.createQuery(hql); qu ...
- Windows内核安全与驱动开发
这篇是计算机中Windows Mobile/Symbian类的优质预售推荐<Windows内核安全与驱动开发>. 编辑推荐 本书适合计算机安全软件从业人员.计算机相关专业院校学生以及有一定 ...