zoukankan      html  css  js  c++  java
  • Autofac入门示例 上 备忘录

    上一篇搞清楚了Autofac是什么东东后,这篇我们就开始说一下他怎么用,Autofac最大的优点就是他太简单方便了,既可以用配置文件,也可以用代码来装配。

    Autofac的装配工作主要是分三步:

    1. 创建一个ContainerBuilder,容器构建器。
    2. 登记服务和组件,就是程序中所用到的实现了指定接口的类。
    3. 注册实例对象,就是把一些实例注册进行,Autofac在用的时候会自已过来拿
    4. 最后生成容器,Autofac会自动的检测依赖关系,然后进行自动装载。
    5. 最最后就是通过构造出来的IContainer取对象实例了。

    弄清楚了步骤现在就看一下官方所给出的示例,范例有两个,一个是备忘录程序,一个是计算器(让我想起了曾经的一个面试题),现在先从备忘录开始吧,原文是英文的,如果英语好的同志直接看原版,英文一般的同志可以听我接下来的唠叨。

    原文:http://www.codeproject.com/KB/architecture/di-with-autofac.aspx (英文)
    源程序:http://www.codeproject.com/KB/architecture/di-with-autofac/autofac-example.zip

    运行后的效果是:

    看一下官方提供的类的关系图:

    首先建一个控制台应用程序,工程名为Remember。偷个懒不截图了,大家都明白吧。现在展示一下这几个核心类是什么样以及它们的功能。

    从上面的类图中我们可以粗略的看出,有一个Memo的类,当然它就是我们的主角(备忘录实体

    View Code
    1 namespace Remember
    2 {
    3     using System;
    4     public class Memo
    5     {
    6         public DateTime DueAt { getset; }
    7         public string Title { getset; }
    8     }
    9 }

    MemoChecker顾名思意就是备忘录检查器,它是用来处理备忘录的工作者。

    View Code
     1 namespace Remember
     2 {
     3     using System;
     4     using System.Linq;
     5 
     6     class MemoChecker
     7     {
     8         IQueryable<Memo> _memos;
     9         IMemoDueNotifier _notifier;
    10 
    11         public MemoChecker(IQueryable<Memo> memos, IMemoDueNotifier notifier)
    12         {
    13             this._memos = memos;
    14             this._notifier = notifier;
    15         }
    16 
    17         public void CheckNow()
    18         {
    19             var overdueMemos = _memos.Where(
    20                 memo => memo.DueAt < DateTime.Now);
    21 
    22             foreach (var memo in overdueMemos)
    23                 _notifier.MemoIsDue(memo);
    24         }
    25     }
    26 }

    还有一个接口IMemoDueNotifier,它是提醒者,该接口被备忘录检查器调用,以便在检查到过期的备忘录实体时提示。

    View Code
    1 namespace Remember
    2 {
    3     interface IMemoDueNotifier
    4     {
    5         void MemoIsDue(Memo memo);
    6     }
    7 }

    具体的提示方式则是由实现了IMemoDueNotifier的具体类来完成的,它们之间的契约是必须继承了TextWriter的类对能作为输出源(比如Console.Out输出到屏幕,StringWriter输出到字符串中,HttpWriter输出到Response.Write流等等),在该示例中实现了PrintingNotifier类来向屏幕中输出过期的备忘录实体。

    View Code
     1 namespace Remember
     2 {
     3     using System.IO;
     4     public class PrintingNotifier : IMemoDueNotifier
     5     {
     6         TextWriter _writer;
     7         public PrintingNotifier(TextWriter writer)
     8         {
     9             _writer = writer;
    10         }
    11 
    12         public void MemoIsDue(Memo memo)
    13         {
    14             _writer.WriteLine("Memo '{0}' is due!", memo.Title);
    15         }
    16     }
    17 }

    这些类都很简单,建议同志们打开VS,引入Autofac然后自己亲自在电脑上敲一遍可以加深印象。而不仅仅时看一遍就过去了,很容易忘记的。

    好了现在我们把刚刚那几个类已经将这些东东都完成了,但是它们还不能一起配合着干起活来。

    最后看一下主程序的代码吧,在这里我们将把这些类都组织起来让他们一起工作。在这里我写了一种传统的直接new的方式,也写了使用Autofac的方式,两个方式运行出来的结果是一样的。但是我们通过Autofac注册的方式来处理系统中的所有类和接口(也称组件和服务)时,它们变得很离散,之间都没有耦合,我们需要什么对象时只需要象本示例中一样调用container.Resolve<MemoChecker>() 这个Resolve方法既可。这样我们就可以灵活的替换多个类。

    View Code
     1 namespace Remember
     2 {
     3     using System;
     4     using System.IO;
     5     using System.Linq;
     6     using Autofac;
     7 
     8     class Program
     9     {
    10         static IQueryable<Memo> memos = new[]{
    11                 new Memo{ Title="Release Autofac 1.0", DueAt = new DateTime(2007,12,14)},
    12                 new Memo{ Title="Write CodeProject Article", DueAt = DateTime.Now},
    13                 new Memo{ Title="Release Autofac 2.3", DueAt = new DateTime(2010,07,01)}
    14             }.AsQueryable();
    15 
    16         static void Main(string[] args)
    17         {
    18             /*
    19              * 以传统的依赖高度耦合的方式创建对象,
    20             IMemoDueNotifier memoDueNotifier = new PrintingNotifier(Console.Out);
    21             MemoChecker chechker = new MemoChecker(memos, memoDueNotifier);
    22             chechker.CheckNow();
    23             */
    24 
    25             //以IoC依赖注入方式创建对象
    26             using (var container = RegisterContainer())
    27                 container.Resolve<MemoChecker>().CheckNow();
    28 
    29             Console.ReadKey();
    30         }
    31 
    32         /// <summary>
    33         /// 注册组件容器
    34         /// </summary>
    35         /// <returns></returns>
    36         private static IContainer RegisterContainer()
    37         {
    38 
    39             //使用了 Autofac 的依赖注入后的方式
    40             //创建构造器
    41             var builder = new ContainerBuilder();
    42 
    43             //登记MemoChecker组件
    44             builder.Register(c => new MemoChecker(
    45                 c.Resolve<IQueryable<Memo>>(),
    46                 c.Resolve<IMemoDueNotifier>())
    47             );
    48 
    49             //登记PrintingNotifier组件
    50             builder.Register(c => new PrintingNotifier(
    51                 c.Resolve<TextWriter>())
    52             ).As<IMemoDueNotifier>();
    53 
    54             //注册实例对象
    55             builder.RegisterInstance(memos);
    56             builder.RegisterInstance(Console.Out).As<TextWriter>().ExternallyOwned();
    57 
    58             //检查依赖关系生成容器
    59             return builder.Build();
    60         }
    61     }
    62 }

      完成了上面这个范例你有些茫然,为什么我们要用如此复杂的方式来获取对象呢?它为我们带来了什么便利呢?这个问题很纠结(其实我第一看设计模式的时候也有这种问题)。

    引用官方的一段话:

    IoC带给了我们一种新的方式解藕在客户代码中直接new的对象,同时它遵循面向接口编程的OO原理,让我们对接口操作而不对具体实现操作,当我们面对程序的变化的时候,就可以增加新的类,然后注册到系统中,而无须修改原来的类和客户代码中所有对该类的引用,这同时也符合了开闭原则。

    说了这么多官话,简单的来说就是让我们不需要在程序发生变化的时候,查找每个引用,然后Ctrl+V,Ctrl+C的重复替换,同样我们也可以动态的改变程序的具体实现方式,就拿我们这个例子来说,我们可以实现个继承自IMemoDueNotifier接口的ASP.NET 通知者,这样我们就可以将结果输出到WEB上了。

    明天再写计算器的讲解吧,在下一篇中将使用配置文件来进行注册,而不象本篇完全的代码注册。

  • 相关阅读:
    python 自定义模块路径问题
    好书一下
    批量修改shell文件
    查看内存占用,排名最高开始
    prosql写法示例
    curl base64 python 请求api地址进行测试服务是否正常
    linxu家目录$ 或者是家目录丢失
    docker 添加普通用户权限
    关系型数据库和非关系型数据库的内在区别
    MapperScan的工作,Spring-Mybatis怎么自动getMapper
  • 原文地址:https://www.cnblogs.com/biyusoft/p/3432065.html
Copyright © 2011-2022 走看看