您的位置:首页 > 移动开发 > Unity3D

[Solution] DI原理解析及Castle、Unity框架使用

2017-05-08 11:06 543 查看
DI介绍控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题.依赖注入(Dependency Injection,英文缩写为DI)是一种设计模式.其实本质都是指同一件事,强调的内容不一样.IoC强调容器的作用,DI强调注入的作用.通常IoC和DI可以理解为一个意思,只是指的对象不同.

DI基本原理

DI本质上是通过容器来反射创建实例. 1个简单的类
1
2
3
4
5
6
7
class
Person

{

public
void
Say()

{

Console.WriteLine(
"Person's say method is Called"
);

}

}

反射代码(className:类的全限定名)
1
2
3
4
5
private
static
object
CreateInstance(Assembly assembly,
string
className)

{

var
type = assembly.GetType(className);

return
type !=
null
? Activator.CreateInstance(type) :
null
;

}

执行(XX为命名空间)
1
2
3
4
5
6
7
8
9
10
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容器创建对象.
1
2
3
4
5
6
7
8
9
10
11
interface
IPerson

{

void
Say();

}

class
Person : IPerson

{

public
void
Say()

{

Console.WriteLine(
"Person's say method is Called"
);

}

}

执行
1
2
3
4
5
6
7
8
9
10
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待注入类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
interface
ITransient

{

 

}

interface
IPerson

{

void
Say();

}

class
Person : IPerson, ITransient

{

public
void
Say()

{

Console.WriteLine(
"Person's say method is Called"
);

}

}

注册解析方式一
1
2
3
4
5
6
7
8
9
10
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();

}

注册解析方式二
1
2
3
4
5
6
7
8
9
10
11
public
class
AssmInstaller : IWindsorInstaller

{

public
void
Install(IWindsorContainer container, IConfigurationStore store)

{

container.Register(Classes.FromThisAssembly()
//选择Assembly

.IncludeNonPublicTypes() 
//约束Type

.BasedOn<ITransient>() 
//约束Type

.WithService.DefaultInterfaces() 
//匹配类型

.LifestyleTransient());
//注册生命周期

}

}

1
2
3
4
5
6
7
8
9
10
static
void
Main(
string
[] args)

{

using
(
var
container =
new
WindsorContainer())

{

container.Install(
new
AssmInstaller());

var
person = container.Resolve<IPerson>();

person.Say();

}

Console.ReadKey();

}

构造函数注入
1
2
3
4
5
6
7
8
9
class
Task : ITransient

{

public
IPerson Person {
get
;
set
;}

public
Task(IPerson person)

{

Person = person;

Person.Say();

}

}

1
2
3
4
5
6
7
8
9
static
void
Main(
string
[] args)

{

using
(
var
container =
new
WindsorContainer())

{

container.Install(
new
AssmInstaller());

container.Resolve<Task>();

}

Console.ReadKey();

}

属性注入
1
2
3
4
5
6
7
8
9
10
11
class
Task : ITransient

{

public
IPerson Person {
get
;
set
;}

public
Task()

{

}

public
void
Say()

{

Person.Say();

}

}

1
2
3
4
5
6
7
8
9
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注册
1
2
3
4
5
6
7
8
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注册
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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待注入类
1
2
3
4
5
6
7
8
9
10
11
public
interface
IPerson

{

void
Say();

}

public
class
Person : IPerson

{

public
void
Say()

{

Console.WriteLine(
"Person's say method is Called"
);

}

}

注册解析一
1
2
3
4
5
6
7
8
9
10
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();

}

注册解析二
1
2
3
4
5
6
7
8
9
10
static
void
Main(
string
[] args)

{

using
(
var
container =
new
UnityContainer())

{

container.RegisterInstance<IPerson>(
new
Person());

var
person = container.Resolve<IPerson>();

person.Say();

}

Console.ReadKey();

}

构造函数注入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class
Task : ITask

{

public
IPerson Person {
get
;
set
;}

public
Task(IPerson person)

{

Person = person;

Person.Say();

}

}

public
interface
ITask

{

}

1
2
3
4
5
6
7
8
9
10
static
void
Main(
string
[] args)

{

using
(
var
container =
new
UnityContainer())

{

container.RegisterInstance<IPerson>(
new
Person());

container.RegisterType<ITask, Task>();

container.Resolve<ITask>();

}

Console.ReadKey();

}

属性注入
1
2
3
4
5
6
7
8
9
10
11
12
13
class
Task : ITask

{

[Dependency]

public
IPerson Person {
get
;
set
;}

public
Task(IPerson person)

{

Person = person;

}

public
void
Say()

{

Person.Say();

}

}

1
2
3
4
5
6
7
8
9
10
11
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注册
1
2
3
4
5
6
7
protected
void
Application_Start()

{

RouteConfig.RegisterRoutes(RouteTable.Routes);

var
container =
new
UnityContainer();

container.RegisterType<IPerson, Person>();

DependencyResolver.SetResolver(
new
UnityDependencyResolver(container));

}

这样Unity就接管了Controller的创建
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  method return public