最近休假了所以没有及时更新这一系列文章,大家见谅。本来想先写NuGet这部分的,但是我觉得NuGet对于大家来说可以先不用话费太多时间,还是先了解下ASP.NET MVC 3中的DI这部分吧。
ASP.NET MVC 3.0学习系列文章--Razor and ASP.NET MVC 3.0
ASP.NET MVC 3.0学习系列文章—Controllers in ASP.NET MVC 3.0
ASP.NET MVC 3.0学习系列文章—Model in ASP.NET MVC 3.0
![image image](https://i-blog.csdnimg.cn/blog_migrate/627878d18e5e4c60c4dc05a7c369cae9.png)
这篇文章主要介绍如下内容:
1.Introduction
对于DI,工作3年以上的开发人员应该都是比较熟悉了。如果你是比较初级的开发人员,我建议可以看看资料,了解下DI以及相关的概念。推荐阅读如下:
http://en.wikipedia.org/wiki/Dependency_injection
http://en.wikipedia.org/wiki/Abstract_factory
http://martinfowler.com/articles/injection.html#UsingAServiceLocator
在ASP.NET MVC 3之前的版本是使用Abstract Factory,Service Locator来作为DI的容器,而在3中你可以使用新的Dependency Resolver来结合Container工具更加简单的实现DI。
2. Dependency Resolution
什么是Dependency Resolution?
一个Controller需要一个Repository,那么这个Repository就是Controller的一个依赖项。
上面是传统的一个Deoendency的使用例子(代码中)。
在ASP.NET MVC 3中提供了Dependency Reolver,它给我们提供了一个好的Dependency Resolution。
当请求中需要某个组件时,Dependency Resolver就会对应的提供一个控件T。
3.Benefits
使用Dependency Resolution有啥好处呢?
a.Flexibility
让整个系统的架构更加灵活。开发人员可以更加专注于架构,而不是功能的实现。
b.Testability
让整个系统的测试更加容易。测试部分和具体的功能实现依赖项要小很多了。
c.Extensibility
可扩展性增强。
4.IdependencyResolver的使用
The DependencyResolver is a member of the System.Web.Mvc NameSpace and its job is quite simple: to provide a central registration point for your chosen IoC Container. Prior to MVC 3, we often dealt with our chosen IoC container directly. In MVC 3, there is an abstraction layer (the DependencyResolver Class) that we will interact with directly. Whether your chosen IoC Container is Windsor, StructureMap or Unity, you can take advantage of this new feature.
IdependencyResolver接口有两个方法:
object GetService(Type serviceType)
IEnumerable<object> GetServices(Type serviceType)
如何使用它呢,一般都是让结合一个IoC Container来使用。
我这里给出几个例子:
结合Autofac使用:
我比较喜欢Autofac,但是发现结合IdependencyResolver来使用Autoc相对还是比较复杂的。需要好好研究研究。
结合StructureMap:
1. public class StructureMapDependencyResolver : IDependencyResolver
2. {
3. IContainer _container;
4.
5. public StructureMapDependencyResolver(IContainer container)
6. {
7. _container = container;
8. }
9.
10.
11. public object GetService(Type serviceType)
12. {
13. object instance = _container.TryGetInstance(serviceType);
14.
15. if (instance == null && !serviceType.IsAbstract)
16. {
17. _container.Configure(c => c.AddType(serviceType, serviceType));
18. instance = _container.TryGetInstance(serviceType);
19. }
20.
21. return instance;
22. }
23.
24. public IEnumerable<object> GetServices(Type serviceType)
25. {
26. return _container.GetAllInstances(serviceType).Cast<object>();
27. }
28. }
结合Unity:
1. public class UnityDependencyResolver : IDependencyResolver
2. {
3. IUnityContainer _container;
4.
5. public UnityDependencyResolver(IUnityContainer container)
6. {
7. _container = container;
8. }
9.
10. public object GetService(Type serviceType)
11. {
12. object instance;
13. try
14. {
15. instance = _container.Resolve(serviceType);
16. if (serviceType.IsAbstract || serviceType.IsInterface)
17. {
18. return null;
19. }
20. return instance;
21. }
22. catch (Exception e)
23. {
24. return null;
25. }
26. }
27.
28. public IEnumerable<object> GetServices(Type serviceType)
29. {
30. return _container.ResolveAll(serviceType);
31. }
32. }
结合NInject:
public class NinjectDependencyResolver : IDependencyResolver
{
private readonly IKernel _kernel;
public NinjectDependencyResolver(IKernel kernel)
{
_kernel = kernel;
}
public object GetService(Type serviceType)
{
return _kernel.TryGet(serviceType, new IParameter[0]);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return _kernel.GetAll(serviceType, new IParameter[0]);
}
}
接下来是就是在Application Start时Register Service并设置Resolver。
StructureMap:
# IContainer container = new Container(
# x =>
# {
# x.For<SomeService>().
# Use<SomeService>().
# WithCtorArg("stringResponse").
# EqualTo("IoC Container: StructureMap.");
#
# x.For<HomeController>().Use<HomeController>();
# });
# DependencyResolver.SetResolver(new StructureMapDependencyResolver(container));
Unity:
#
# var container = new UnityContainer();
#
# container
# .RegisterType<SomeService, SomeService>().
# Configure<InjectedMembers>().ConfigureInjectionFor
# <SomeService>(new InjectionConstructor("IoC Container: Unity."));
#
# container.RegisterType<HomeController, HomeController>();
#
# DependencyResolver.SetResolver(new UnityDependencyResolver(container));
NInject:
var kernel = new StandardKernel();
kernel.Bind<IMessenger>().To<SmsMessenger>();
kernel.Bind<IFilterProvider>().To<MessagingFilterProvider>();
DependencyResolver.SetResolver(new NinjectDependencyResolver(kernel));
5.Controller Injection:
6.View Injection:
关于Activator和ViewEngine我们另外写一文章介绍。
Nick