ASP.NET 5:依赖注入
ASP.NET 5:依赖注入
1.背景
如果某个具体的(或类)对象被客户程序所依赖,通常把它们抽象成抽象类或接口。简单说,客户程序摆脱所依赖的具体类型,称之为面向接口编程。
那么问题来了?如何选择客户程序所需要的实现类?在使用创建型模式下创建对象是不难解决这个问题。
但如果设计的不是具体业务逻辑,而是公共类库或框架程序,对外只提供抽象而已,该如何把外部使用的类型传递给它们?
我们可以采用“依赖注入”的方式,将加工好的抽象类型实体“注入”到客户程序中。
注:依赖注入DI(Dependency Injection),它和控制反转IOC(Inversion of Control)是同一个意思,不同术语叫法。
2.场景
客户程序获取年份,我们先设计一个接口:

using System; namespace Blog.Consoles
{
public interface ITimeProvider
{
DateTime CurrentDate { get; }
}
}

并对这个接口实现(可以多种实现哦,这也是设计接口的原因):

using System; namespace Blog.Consoles
{
public class TimeProvider : ITimeProvider
{
public DateTime CurrentDate
{
get { return DateTime.Now; }
}
}
}

那么我们在客户程序使用:

using System; namespace Blog.Consoles
{
class Program
{
static void Main(string[] args)
{
ITimeProvider tp = new TimeProvider();
Console.WriteLine(tp.CurrentDate.Year); Console.ReadKey();
}
}
}

这样实现的依赖关系是:

显然这样客户程序还需要知道具体类型TimeProvider,我们增加一个对象:

using System;
using System.Collections.Generic; namespace Blog.Consoles
{
public class Assembler
{
//保存抽象类型和实体类型
static Dictionary<Type, Type> d = new Dictionary<Type, Type>(); static Assembler()
{
//注册抽象类型需要使用的实体类型
d.Add(typeof(ITimeProvider), typeof(TimeProvider));
} public object Create(Type type)
{
if ((type == null) || !d.ContainsKey(type))
{
throw new NullReferenceException();
} return Activator.CreateInstance(d[type]);
} public T Create<T>()
{
return (T)Create(typeof(T));
}
}
}

此时再改造依赖关系:

这样客户程序只依赖Assembler和ITimeProvider,并不知道TimeProvider存在。
接下来如何写注入代码?下面分几种方式。
3.构造注入
构造注入使用构造方法,通过Assembler或其它机制把抽象类型作为参数传递。其实现代码:

using System; namespace Blog.Consoles
{
class Program
{
public ITimeProvider _tp;
public Program(ITimeProvider tp)
{
_tp = tp;
} public int GetYear()
{
return _tp.CurrentDate.Year;
} static void Main(string[] args)
{
ITimeProvider time = new Assembler().Create<ITimeProvider>();
Program p = new Program(time);
Console.WriteLine(p.GetYear()); Console.ReadKey();
}
}
}

4.设置注入
通过属性方法赋值实现的,相对于构造方法一次性注入的方式,设置注入可以在需要时有更改的机会。实现代码:

using System; namespace Blog.Consoles
{
class Program
{
public ITimeProvider _tp { get; set; } public int GetYear()
{
return _tp.CurrentDate.Year;
} static void Main(string[] args)
{
ITimeProvider time = new Assembler().Create<ITimeProvider>(); Program p = new Program();
p._tp = time; Console.WriteLine(p.GetYear()); Console.ReadKey();
}
}
}

还可以简写:

using System; namespace Blog.Consoles
{
class Program
{
public ITimeProvider _tp { get; set; } public int GetYear()
{
return _tp.CurrentDate.Year;
} static void Main(string[] args)
{
var p = new Program() { _tp = new Assembler().Create<ITimeProvider>() }; Console.WriteLine(p.GetYear()); Console.ReadKey();
}
}
}

5.MEF注入
导出部件:

下面不使用Assembler对象,实现代码:

using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection; namespace Blog.Consoles
{
class Program
{
private static CompositionContainer container; private void Compose()
{
var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
container = new CompositionContainer(catalog);
//将部件和宿主程序添加到组合容器
container.ComposeParts(this, new TimeProvider());
} //导入部件
[Import]
public ITimeProvider _tp { get; set; } public int GetYear()
{
return _tp.CurrentDate.Year;
} static void Main(string[] args)
{
var p = new Program();
p.Compose(); Console.WriteLine(p.GetYear()); Console.ReadKey();
}
}
}

6.ASP.NET 5注入
修改Startup.cs:

测试:

7.小结
关于依赖注入的方式,还有接口注入,自定义特性等(它们之间区别和选择,自行体会或查资料),不常用就不说了。
感受到ASP.NET 5自带DI爽就行啦!(ASP.NET 5真的海皮啦!)
后面的帖子,进入项目实战了,最近比较忙,请园友保持耐心。
ASP.NET 5:依赖注入的更多相关文章
- # ASP.NET Core依赖注入解读&使用Autofac替代实现
标签: 依赖注入 Autofac ASPNETCore ASP.NET Core依赖注入解读&使用Autofac替代实现 1. 前言 2. ASP.NET Core 中的DI方式 3. Aut ...
- 实现BUG自动检测 - ASP.NET Core依赖注入
我个人比较懒,能自动做的事绝不手动做,最近在用ASP.NET Core写一个项目,过程中会积累一些方便的工具类或框架,分享出来欢迎大家点评. 如果以后有时间的话,我打算写一个系列的[实现BUG自动检测 ...
- [译]ASP.NET Core依赖注入深入讨论
原文链接:ASP.NET Core Dependency Injection Deep Dive - Joonas W's blog 这篇文章我们来深入探讨ASP.NET Core.MVC Core中 ...
- asp.net core 依赖注入几种常见情况
先读一篇注入入门 全面理解 ASP.NET Core 依赖注入, 学习一下基本使用 然后学习一招, 不使用接口规范, 直接写功能类, 一般情况下可以用来做单例. 参考https://www.cnblo ...
- ASP.NET Core依赖注入——依赖注入最佳实践
在这篇文章中,我们将深入研究.NET Core和ASP.NET Core MVC中的依赖注入,将介绍几乎所有可能的选项,依赖注入是ASP.Net Core的核心,我将分享在ASP.Net Core应用 ...
- 自动化CodeReview - ASP.NET Core依赖注入
自动化CodeReview系列目录 自动化CodeReview - ASP.NET Core依赖注入 自动化CodeReview - ASP.NET Core请求参数验证 我个人比较懒,能自动做的事绝 ...
- ASP.NET Core 依赖注入最佳实践——提示与技巧
在这篇文章,我将分享一些在ASP.NET Core程序中使用依赖注入的个人经验和建议.这些原则背后的动机如下: 高效地设计服务和它们的依赖. 预防多线程问题. 预防内存泄漏. 预防潜在的BUG. 这篇 ...
- ASP.NET Core依赖注入最佳实践,提示&技巧
分享翻译一篇Abp框架作者(Halil İbrahim Kalkan)关于ASP.NET Core依赖注入的博文. 在本文中,我将分享我在ASP.NET Core应用程序中使用依赖注入的经验和建议. ...
- ASP.NET Core依赖注入解读&使用Autofac替代实现【转载】
ASP.NET Core依赖注入解读&使用Autofac替代实现 1. 前言 2. ASP.NET Core 中的DI方式 3. Autofac实现和自定义实现扩展方法 3.1 安装Autof ...
- ASP.NET Core 依赖注入基本用法
ASP.NET Core 依赖注入 ASP.NET Core从框架层对依赖注入提供支持.也就是说,如果你不了解依赖注入,将很难适应 ASP.NET Core的开发模式.本文将介绍依赖注入的基本概念,并 ...
随机推荐
- C++11并行编程-条件变量(condition_variable)详细说明
<condition_variable >头文件主要包含有类和函数相关的条件变量. 包括相关类 std::condition_variable和 std::condition_variab ...
- hdu 4856 Tunnels(bfs+状态压缩)
题目链接:hdu 4856 Tunnels 题目大意:给定一张图,图上有M个管道,管道给定入口和出口,单向,如今有人想要体验下这M个管道,问最短须要移动的距离,起点未定. 解题思路:首先用bfs处理出 ...
- docker 现实---联网多台物理主机,容器桥到物理网络(三)
docker 默认桥接卡docker0 只有当这个单元中的所有容器桥接卡.例如,在主机虚拟网络适配器容器看通常称为veth*** 和docker只要把这些卡桥接在一起,例如下面的附图: waterm ...
- SQL Server高可用——日志传送(4-1)——概论
原文:SQL Server高可用--日志传送(4-1)--概论 本文作为学习总结,部分内容出自联机丛书及其他书籍 日志传送是什么? SQLServer 2012之前(2012出现了AlwaysOn), ...
- RH253读书笔记(4)-Lab 4 The Domain Name System
Lab 4 The Domain Name System Goal: To install and configure a DNS server System Setup: Throughout th ...
- 一天JavaScript示例-判定web页面的区域
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- .NET应用架构设计—再次了解分层架构(现代企业应用分层架构核心设计元素)
阅读文件夹: 1.背景介绍 2.简要回想下传统三层架构 3.企业级应用分层架构(现代分层架构的基本演变过程) 3.1.服务层中应用契约式设计来解决动态条件不匹配错误(通过契约式设计模式来将问题在线下暴 ...
- stringstream转换CString为string出错
使用stringstream转换CString为string时,调试时发现是CString赋给stringstream没有问题,stringstram赋给string就不行,倒也不是没有赋成功,只是赋 ...
- SQL Server 2008性能故障排查(四)——TempDB
原文:SQL Server 2008性能故障排查(四)--TempDB 接着上一章:I/O TempDB: TempDB是一个全局数据库,存储内部和用户对象还有零食表.对象.在SQLServer操作过 ...
- 跟我一起学extjs5(37--单个模块的设计[5取得模块列表数据])
跟我一起学extjs5(37--单个模块的设计[5取得模块列表数据]) 写了几个月,总算有点盼头了,最终要从后台取得数据了.后台的spring mvc 和 service 仅仅能简单的 ...