工欲善其事,必先利其器——Autofac

工欲善其事,必先利其器——Autofac

Autofac,我的理解是,和工厂类似,可以通过修改配置文件选择不同的实现方式而不用重新编译代码。

下面是几篇篇转载的文章:

Autofac为何物?它是.NET世界里现存的几种IOC框架其中之一,传说是速度最快的一个,同类的框架还有用过Castle WindsorStructureMapUnity等,如果你用过其中之一,那就好办了*^_^*。什么?你不知道什么是IOC,好吧,这里有一篇文章是讲解IOC是何物的,IOC中文名被称为依赖注入,看一下Martin Fowler大师写的《IoC容器和 Dependency Injection 模式 》

通过上面的了解,我们基本上已经明白了Autofac为何物了,现在了解一下它相对于其它的IoC框架有什么优点:

  1. 它是C#语言联系很紧密,也就是说C#里的很多编程方式都可以为Autofac使用,例如可以用Lambda表达式注册组件。
  2. 较低的学习曲线,学习它非常的简单,只要你理解了IoC和DI的概念以及在何时需要使用它们。
  3. XML配置支持。
  4. 自动装配。
  5. 与Asp.Net MVC 3集成。
  6. 微软的Orchad开源程序使用的就是Autofac,从该源码可以看出它的方便和强大。

性能上面呢,有人为其做了测试:

说了这么多,在哪里可以得到它呢?你可以直接点击这里下载Autofac-Net4.0 ,也可以去它的官方网站上http://code.google.com/p/autofac/(英文)上获取最新的信息。

这一篇是介绍篇,不涉及代码,主要是先了解一下该组件。

Autofac是一款IOC框架,比较于其他的IOC框架,如Spring.NET,Unity,Castle等等所包含的,它很轻量级性能上也是很高的。于是,今天抽空研究了下它。下载地址:http://code.google.com/p/autofac/downloads/list

1)解压它的压缩包,主要看到Autofac.dll,Autofac.Configuration.dll,这也是本篇文章重点使用的Autofac的类库。

2)创建一个控制台工程,并且引用以上的DLL文件。创建一个数据库操作接口IDatabase.cs:

/// <summary>
/// Database operate interface
/// </summary>
public interface IDatabase
{
string Name { get; }

void Select(string commandText);

void Insert(string commandText);

void Update(string commandText);

void Delete(string commandText);
}

这里包含CRUD四种操作的方法。

3)创建两种数据库的操作类,SqlDatabase.cs以及OracleDatabase.cs:

public class SqlDatabase : IDatabase 

    public string Name 
    { 
        get { return "sqlserver"; } 
    }

public void Select(string commandText) 
    { 
        Console.WriteLine(string.Format("‘{0}‘ is a query sql in {1}!", commandText, Name)); 
    }

public void Insert(string commandText) 
    { 
        Console.WriteLine(string.Format("‘{0}‘ is a insert sql in {1}!", commandText, Name)); 
    }

public void Update(string commandText) 
    { 
        Console.WriteLine(string.Format("‘{0}‘ is a update sql in {1}!", commandText, Name)); 
    }

public void Delete(string commandText) 
    { 
        Console.WriteLine(string.Format("‘{0}‘ is a delete sql in {1}!", commandText, Name)); 
    } 
}

以及

public class OracleDatabase : IDatabase 

    public string Name 
    { 
        get { return "oracle"; } 
    }

public void Select(string commandText) 
    { 
        Console.WriteLine(string.Format("‘{0}‘ is a query sql in {1}!", commandText, Name)); 
    }

public void Insert(string commandText) 
    { 
        Console.WriteLine(string.Format("‘{0}‘ is a insert sql in {1}!", commandText, Name)); 
    }

public void Update(string commandText) 
    { 
        Console.WriteLine(string.Format("‘{0}‘ is a update sql in {1}!", commandText, Name)); 
    }

public void Delete(string commandText) 
    { 
        Console.WriteLine(string.Format("‘{0}‘ is a delete sql in {1}!", commandText, Name)); 
    } 
}

4)接着创建一个数据库管理器DatabaseManager.cs:

public class DatabaseManager 

    IDatabase _database;

public DatabaseManager(IDatabase database) 
    { 
        _database = database; 
    }

public void Search(string commandText) 
    { 
        _database.Select(commandText); 
    }

public void Add(string commandText) 
    { 
            _database.Insert(commandText); 
    }

public void Save(string commandText) 
    { 
            _database.Update(commandText); 
    }

public void Remove(string commandText) 
    { 
            _database.Delete(commandText); 
    }

}

5)在控制台中,编写以下测试程序:

var builder = new ContainerBuilder(); 
builder.RegisterType<DatabaseManager>(); 
builder.RegisterType<SqlDatabase>().As<IDatabase>(); 
using (var container = builder.Build()) 

    var manager = container.Resolve<DatabaseManager>(); 
    manager.Search("SELECT * FORM USER"); 
}

运行结果:

分析:

这里通过ContainerBuilder方法RegisterType对DatabaseManager进行注册,当注册的类型在相应得到的容器中可以Resolve你的DatabaseManager实例。

builder.RegisterType<SqlDatabase>().As<IDatabase>();通过AS可以让DatabaseManager类中通过构造函数依赖注入类型相应的接口。

Build()方法生成一个对应的Container实例,这样,就可以通过Resolve解析到注册的类型实例。

同样地,如果你修改数据库类型注册为:

builder.RegisterType<OracleDatabase>().As<IDatabase>();

运行结果:

6)显然以上的程序中,SqlDatabase或者OracleDatabase已经暴露于客户程序中了,现在我想将该类型选择通过文件配置进行读取。Autofac自带了一个Autofac.Configuration.dll 非常方便地对类型进行配置,避免了程序的重新编译。

修改App.config:

<configuration> 
  <configSections> 
    <section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration"/> 
  </configSections> 
  <autofac defaultAssembly="AutofacDemo"> 
    <components> 
      <component type="AutofacDemo.SqlDatabase, AutofacDemo" service="AutofacDemo.IDatabase" /> 
    </components> 
  </autofac> 
</configuration>

通过Autofac.Configuration.SectionHandler配置节点对组件进行处理。

对应的客户端程序改为:

var builder = new ContainerBuilder(); 
builder.RegisterType<DatabaseManager>(); 
builder.RegisterModule(new ConfigurationSettingsReader("autofac")); 
using (var container = builder.Build()) 

    var manager = container.Resolve<DatabaseManager>(); 
    manager.Search("SELECT * FORM USER"); 
}

运行结果:

7)另外还有一种方式,通过Register方法进行注册:

var builder = new ContainerBuilder(); 
//builder.RegisterType<DatabaseManager>(); 
builder.RegisterModule(new ConfigurationSettingsReader("autofac")); 
builder.Register(c => new DatabaseManager(c.Resolve<IDatabase>())); 
using (var container = builder.Build()) 

    var manager = container.Resolve<DatabaseManager>(); 
    manager.Search("SELECT * FORM USER"); 
}

得到结果也是一样的。

8)现在我想通过一个用户类来控制操作权限,比如增删改的权限,创建一个用户类:

/// <summary> 
/// Id Identity Interface 
/// </summary> 
public interface Identity 

    int Id { get; set; } 
}

public class User : Identity 

    public int Id { get; set; } 
    public string Name { get; set; } 
}

修改DatabaseManager.cs代码:

public class DatabaseManager 

    IDatabase _database; 
    User _user;

public DatabaseManager(IDatabase database) : this(database, null) 
    { 
    }

public DatabaseManager(IDatabase database, User user) 
    { 
        _database = database; 
        _user = user; 
    }

/// <summary> 
    /// Check Authority 
    /// </summary> 
    /// <returns></returns> 
    public bool IsAuthority() 
    { 
        bool result = _user != null && _user.Id == 1 && _user.Name == "leepy" ? true : false; 
        if (!result) 
            Console.WriteLine("Not authority!");

return result; 
    }

public void Search(string commandText) 
    { 
        _database.Select(commandText); 
    }

public void Add(string commandText) 
    { 
        if (IsAuthority()) 
            _database.Insert(commandText); 
    }

public void Save(string commandText) 
    { 
        if (IsAuthority()) 
            _database.Update(commandText); 
    }

public void Remove(string commandText) 
    { 
        if (IsAuthority()) 
            _database.Delete(commandText); 
    } 
}

在构造函数中增加了一个参数User,而Add,Save,Remove增加了权限判断。

修改客户端程序:

User user = new User { Id = 1, Name = "leepy" }; 
var builder = new ContainerBuilder(); 
builder.RegisterModule(new ConfigurationSettingsReader("autofac")); 
builder.RegisterInstance(user).As<User>(); 
builder.Register(c => new DatabaseManager(c.Resolve<IDatabase>(), c.Resolve<User>()));

using (var container = builder.Build()) 

    var manager = container.Resolve<DatabaseManager>();

manager.Add("INSERT INTO USER ..."); 
}

运行结果:

分析:

builder.RegisterInstance(user).As<User>();注册User实例。

builder.Register(c
=> new DatabaseManager(c.Resolve<IDatabase>(),
c.Resolve<User>()));通过Lampda表达式注册DatabaseManager实例。

如果这里我修改User的属性值:

User
user = new User { Id = 2, Name = "zhangsan" };

运行结果:

说明该用户无权限操作。

时间: 2024-08-24 00:37:21

工欲善其事,必先利其器——Autofac的相关文章

工欲善其事必先利其器--------搭建Android平台

工欲善其事必先利其器--------搭建Android平台 1.1            安装JDK 在Eclipse的开发过程中需要JDK或JRE的支持,否则会报错. (1)     下载JDK(建议去JDK官网下载)[Java SE Downloads 中的Java platform(JDK)](最好不要安装在带空格的目录下) 图1-1 JDK下载 (2)     配置环境变量(此步骤很重要,过程可参照网上步骤) JAVA_HOME:  C:\Program Files\Java\jdk1.

转:【工欲善其事必先利其器】—Entity Framework实例详解

开始本篇文章之前,先说一下Entity Framework 6 Alpha1在NuGet中已可用,原文链接http://blogs.msdn.com/b/adonet/archive/2012/10/30/ef6-alpha-1-available-on-nuget.aspx 俗话说:“工欲善其事必先利其器”,在深入讲解Entity Framework之前,先准备一下开发工具以及前期的配置. 一.开发工具 开发工具基本略过,这里说一下,我使用的是Visual Studio 2012,Entity

工欲善其事必先利其器—成绩登统系统

    工欲善其事必先利其器.谓工匠想要使他的工作做好,一定要先让工具锋利.比喻要做好一件事,准备工作非常重要.语出孔子·<论语·卫灵公>:子贡问为仁.子曰:"工欲善其事,必先利其器.居是邦也,事其大夫之贤者,友其士之仁者." 也就是我们通常所说的磨刀不误砍柴工.那么体现在系统或者软件开发上磨刀就是前期的准备工作,也就是各个文档编写以及原型的画出与完善. 1.      第一阶段:需求调研     毛主席说过,"没有调查就没有发言权":一切的需求来自于实

单片机开发——01工欲善其事必先利其器(Keil软件安装破解)

本文是博主<单片机开发>博客第一篇文章,主要讲述51单片机编程软件Keil uVision4的安装及破解过程. 1. Keil uVision4安装包文件 PATH:链接:https://pan.baidu.com/s/1IEUUhND_0F_6pXVbhlJamQ 密码:dqrd 安装包内容:安装文件.破解机.汉化包(不建议汉化). 2. Keil uVision4软件安装 双击安装包,一直"NEXT"到最后,选择Finish,到这里软件的安装过程完成. 3. Keil

工欲善其事,必先利其器-Python编辑器选择(2)

前言:工欲善其事.必先利其器 一款顺手的好的编辑器可以让程序员写代码更得心应手,效率也会更高,但是编辑器本身没有好坏,只有使用者使用起来是否顺手而已,这里简单给大家介绍几款常用的可以编辑Python的软件. 一.终端直接编写 windows系统:Win+r,然后在运行框中输入cmd即可打开终端. MAC系统:可以在Launchpad中直接打开终端. 简单说明(针对上图数字处说明) 1.Python3:说明我们的代码是使用的python3的版本,目前有python2和python3两个版本,毫无疑

工欲善其事必先利其器-Notepad++使用小记(Python)

大学开始就一直使用Notepad++ 作为代码编辑器,喜欢它的简洁明了,喜欢它的个性,也喜欢它各种各样骚气的插件. 今天闲来无事,写篇文章记录一下平时使用的种种,包括但不限于个性化使用一些宏,快捷键,相关的命令以及一些个人用的比较多的插件. 本人平时代码最多的也是Python-web相关方面的代码编写,所以这里着重(或者是主要)介绍一些如何将Notepad++打造的适合Python开发. Norepad++ 简介,看看它的主页就明白了 贴一段百科上面的介绍(via): Notepad++是一套非

[2]工欲善其事必先利其器-------UML中的几种常见关系(二)

目录 1.UML类图中几种常见的关系 经过(一)中介绍,我选择的是StarUML作为UML的学习工具,个人喜好,至少在功能上能够满足我现在的需求, 在介绍StarUML的使用之前首先介绍下UML中几种常见的关系: UML类图中常见的关系按照关系的强弱可分为:泛化 ,实现 ,组合, 聚合 , 依赖这几种 1.泛化关系:是一种继承关系,也就是XX is a kind of XX 描述. 2.实现关系:是一种类与接口的关系. 3. 组合关系:是一种强关联,属于一种整体与部分的关系,但是部分不能离开整体

网易云课堂_C++程序设计入门(下)_第11单元:工欲善其事必先利其器 - STL简介_第11单元 - 单元作业1:OJ编程 - vector 与 sort

第11单元 - 单元作业1:OJ编程 - vector 与 sort 查看帮助 返回 温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业截止时间之前不限次数提交答案,系统将取其中的最高分作为最终成绩. 本次作业练习使用 vector 容器以及 sort 算法,对输入的数据进行排序 依照学术诚信条款,我保证此作业是本人独立完成的. 1 本次作业练习使用 vector 容器以及 sort 算法,对输入的数据进行排序(5分) 题目的具体内容参见 [第

工欲善其事必先利其器之搜索引擎

众所周知,搜索引擎在我们生活里面是离不开的,特别是对一个程序员来说能够好好的利用好这个资源可以使我们的做事的效率提高很多,,达到事倍功半的效果!今天我们就来看一看如何优雅的使用搜索引擎!     1.简单查询.在搜索引擎中输入关键词,然后点击“搜索”就行了,系统很快会返回查询结果,这是最简单的查询方法,使用方便,但是查询的结果却不准确,可能包含着许多无用的信息. 2. 使用双引号用(" ").给要查询的关键词加上双引号(半角,以下要加的其它符号同此),可以实现精确的查询,这种方法要求查