1 构建应用程序

示例: 我们期望有一个输出工具类,当前希望通过控制台(console)输出,但是又希望仅能在控制台模式下输出。所以我们把输出抽象为一个接口

using System;

namespace AutofacDemo
{
public interface IOutput
{
void Write(string content);
} public class ConsoleOutput : IOutput
{
public void Write(string content)
{
Console.WriteLine(content);
}
}
}

通过这个接口,我可以在控制台输出任意内容。 现在针对日期进行输出,我可以输出当前日期,明天,或者后天,或者…  我希望输出的日期很灵活。一个日期输出接口

 public interface IDateWriter
{
void WriteDate();
} public class CurentDateWriter :IDateWriter
{
IOutput _output;
public CurentDateWriter(IOutput output)
{
this._output = output;
} public void WriteDate()
{
this._output.Write(DateTime.Now.ToString());
}
}

到此,我们的应用程序构建完毕,CurrentDateWriter 依赖 Ioutput 接口,并通过构造函数进行了注入。

using System;
namespace AutofacDemo
{
class Program
{
static void Main(string[] args)
{
IOutput ioutput = new ConsoleOutput();
IDateWriter idatewriter = new CurentDateWriter(ioutput); idatewriter.WriteDate(); Console.ReadKey();
}
}
}

main 函数的调用代码,很明显对组件类(ConsoleOoutput 和 CurrentDateWriter) 形成了New 依赖。 接下来使用Autofac 实现依赖注入 (DI)

2 引用Autofac

打开项目,在管理Nuget程序包 中,输入aufofac  添加引用

也可以使用命令形式进行安装

PM> install-package aufofac

Autofac  需要一个 ContainerBuilder  来对 组件(实现类)和接口 进行注册,对外部调用代码,只暴露接口。Main 函数修改如下:

using System;
using Autofac;
namespace AutofacDemo
{
class Program
{
static IContainer container { get; set; }
static void Main(string[] args)
{
var builder = new ContainerBuilder();
//注册 【组件类】 作为 【接口】 的实现
builder.RegisterType<ConsoleOutput>().As<IOutput>();
builder.RegisterType<CurentDateWriter>().As<IDateWriter>(); container = builder.Build(); //构建容器 //使用
IDateWriter datawriter = container.Resolve<IDateWriter>();
datawriter.WriteDate(); Console.ReadKey();
}
}
}

我们把接口实例化的工作交给autofac 容器后,使用Idaewriter 输出日期时,就不用关心它的具体实现了。

3  应用程序执行

在应用程序执行期间,需要确保使用的组件已经被注册,而且是在一个生命周期内。autofac 容器有自己的生命周期, 不推荐直接从容器中取出一个组件。这等于直接new 了很多实例,然后等待系统自动释放。

推荐是在容器的生命周期范围内,获取一个组件时,为这个组件创建一个子生命周期。这样,当结束这个生命周期时,立即释放这个组件,避免内存堆积造成的内存泄露(memory leak)。

所以,我们改变我们上面的代码,附加一个使用范围

using System;
using Autofac;
namespace AutofacDemo
{
class Program
{
static IContainer container { get; set; }
static void Main(string[] args)
{
var builder = new ContainerBuilder();
//注册 【组件类】 作为 【接口】 的实现
builder.RegisterType<ConsoleOutput>().As<IOutput>();
builder.RegisterType<CurentDateWriter>().As<IDateWriter>(); container = builder.Build(); //构建容器 //使用
using (var scope = container.BeginLifetimeScope())
{
IDateWriter datawriter = container.Resolve<IDateWriter>();
datawriter.WriteDate();
}
Console.ReadKey();
}
}
}

当执行WriteDate 方法时过程是这样:

  • WriteDate 方法向  autofac 容器请求一个 IDataWriter
  • autofac 发现 IDataWriter 映射到 CurrentDataWriter , 所以开始 实例化创建 CurrentDataWriter
  • autofac 发现 CurrentDataWriter  构造函数需要传递一个 IOutput 接口
  • autofac 发现 IOutput 映射到 ConsoleOutput 类,于是开始创建 ConsoleOutput  的实例
  • aufofac  用 ConsoleOutput   的实例 完成 CurrentDataWriter 实例的创建
  • aufofac 用 CurrentDataWriter  的实例 来构造 IDataWriter 接口

最新文章

  1. PHP 记录日志
  2. 开源的即时通讯框架 (endv.cn) (一)
  3. rabbitmq启动异常之error,{not_a_dets_file recovery.dets
  4. Linux 环境下如何使 Chrome 浏览器字体更漂亮
  5. mysql 5.6 binlog组提交1
  6. extern “C”的作用
  7. bzoj1009
  8. UIImagePickerController 操作图库
  9. WCF入门教程系列二
  10. MVP模式在Android开发中的应用
  11. Html在线编辑器--基于Jquery的xhEditor轻量级编辑器
  12. 第二次spring会议
  13. C#复习正则表达式
  14. Intellij IDEA 自动清除无效 import 和 清除无效 import 的快捷键 ctrl+alt+o
  15. SQL Server中利用正则表达式替换字符串
  16. JavaWeb基础—JDBC(二)事务与批处理
  17. 2017-2018-1 20162307 Dijkstra算法
  18. 。一个通俗易懂的HMM例子
  19. Qt 反射
  20. realproxy

热门文章

  1. lxml库介绍及实例
  2. Nginx反向代理、负载均衡功能
  3. Java版多人聊天室
  4. SOAP介绍,为学习WCF做准备
  5. 那些你常用的JSP知识
  6. Protocol Buffers教程
  7. JSON.stringify使用
  8. Disruptor之粗糙认识
  9. 在 Eclipse Juno 上安装 Marketplace
  10. 18_Condition条件