AutoFac是.net平台下的IOC容器产品,它可以管理类之间的复杂的依赖关系。在使用方面主要是register和resolve两类操作。 这篇文章用单元测试的形式列举了AutoFac的常用使用方法:

注册部分

使用RegisterType进行注册

[Fact]
public void can_resolve_myclass()
{
var builder = new ContainerBuilder();
builder.RegisterType<MyClass>(); IContainer container = builder.Build();
var myClass = container.Resolve<MyClass>();
Assert.NotNull(myClass);
}

注册为接口

 [Fact]
public void register_as_interface()
{
var builder = new ContainerBuilder();
builder.Register(c => new MyClass()).As<MyInterface>(); IContainer container = builder.Build();
Assert.NotNull(container.Resolve<MyInterface>());
Assert.Throws(typeof (ComponentNotRegisteredException), () => container.Resolve<MyClass>());
}

使用lambda表达式进行注册

[Fact]
public void can_register_with_lambda()
{
var builder = new ContainerBuilder();
builder.Register(c => new MyClass()); IContainer container = builder.Build();
var myClass = container.Resolve<MyClass>();
Assert.NotNull(myClass);
}

带构造参数的注册

[Fact]
public void register_with_parameter()
{
var builder = new ContainerBuilder();
builder.Register(c => new MyParameter());
builder.Register(c => new MyClass(c.Resolve<MyParameter>()));
IContainer container = builder.Build();
Assert.NotNull(container.Resolve<MyClass>());
}

带属性赋值的注册

[Fact]
public void register_with_property()
{
var builder = new ContainerBuilder();
builder.Register(c => new MyProperty());
builder.Register(
c => new MyClass()
{
Property = c.Resolve<MyProperty>()
});
IContainer container = builder.Build();
var myClass = container.Resolve<MyClass>();
Assert.NotNull(myClass);
Assert.NotNull(myClass.Property);
}

Autofac分离了类的创建和使用,这样可以根据输入参数(NamedParameter)动态的选择实现类。

[Fact]
public void select_an_implementer_based_on_parameter_value()
{
var builder = new ContainerBuilder();
builder.Register<IRepository>((c, p) =>
{
var type = p.Named<string>("type");
if (type == "test")
{
return new TestRepository();
}
else
{
return new DbRepository();
}
}).As<IRepository>(); IContainer container = builder.Build();
var repository = container.Resolve<IRepository>(new NamedParameter("type", "test"));
Assert.Equal(typeof(TestRepository),repository.GetType());
}

AufoFac也可以用一个实例来注册,比如用在单例模式情况下:

  [Fact]
public void register_with_instance()
{
var builder = new ContainerBuilder();
builder.RegisterInstance(MyInstance.Instance).ExternallyOwned();
IContainer container = builder.Build();
var myInstance1 = container.Resolve<MyInstance>();
var myInstance2 = container.Resolve<MyInstance>();
Assert.Equal(myInstance1,myInstance2);
}

注册open generic类型

[Fact]
public void register_open_generic()
{
var builder = new ContainerBuilder();
builder.RegisterGeneric(typeof (MyList<>));
IContainer container = builder.Build();
var myIntList = container.Resolve<MyList<int>>();
Assert.NotNull(myIntList);
var myStringList = container.Resolve<MyList<string>>();
Assert.NotNull(myStringList);
}

对于同一个接口,后面注册的实现会覆盖之前的实现

 [Fact]
public void register_order()
{
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<DbRepository>().As<IRepository>();
containerBuilder.RegisterType<TestRepository>().As<IRepository>(); IContainer container = containerBuilder.Build();
var repository = container.Resolve<IRepository>();
Assert.Equal(typeof(TestRepository), repository.GetType());
}

如果不想覆盖的话,可以用PreserveExistingDefaults,这样会保留原来注册的实现。

 [Fact]
public void register_order_defaults()
{
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<DbRepository>().As<IRepository>();
containerBuilder.RegisterType<TestRepository>().As<IRepository>().PreserveExistingDefaults(); IContainer container = containerBuilder.Build();
var repository = container.Resolve<IRepository>();
Assert.Equal(typeof (DbRepository), repository.GetType());
}

可以用Name来区分不同的实现,代替As方法

[Fact]
public void register_with_name()
{
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<DbRepository>().Named<IRepository>("DB");
containerBuilder.RegisterType<TestRepository>().Named<IRepository>("Test"); IContainer container = containerBuilder.Build();
var dbRepository = container.ResolveNamed<IRepository>("DB");
var testRepository = container.ResolveNamed<IRepository>("Test");
Assert.Equal(typeof(DbRepository), dbRepository.GetType());
Assert.Equal(typeof(TestRepository), testRepository.GetType());
}

如果一个类有多个构造函数的话,可以在注册时候选择不同的构造函数

[Fact]
public void choose_constructors()
{
var builder = new ContainerBuilder();
builder.RegisterType<MyParameter>();
builder.RegisterType<MyClass>().UsingConstructor(typeof (MyParameter));
IContainer container = builder.Build();
var myClass = container.Resolve<MyClass>();
Assert.NotNull(myClass);
}

AutoFac可以注册一个Assemble下所有的类,当然,也可以根据类型进行筛选

[Fact]
public void register_assembly()
{
var builder = new ContainerBuilder();
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).
Where(t => t.Name.EndsWith("Repository")).
AsImplementedInterfaces(); IContainer container = builder.Build();
var repository = container.Resolve<IRepository>();
Assert.NotNull(repository);
}

Autofac基本使用(转载)的更多相关文章

  1. AutoFac控制反转 转载https://blog.csdn.net/u011301348/article/details/82256791

    一.AutoFac介绍 Autofac是.NET里IOC(Inversion of Control,控制反转)容器的一种,同类的框架还有Spring.NET,Unity,Castle等.可以通过NuG ...

  2. .NET领域最为流行的IOC框架之一Autofac WebAPI2使用Autofac实现IOC属性注入完美解决方案 AutoFac容器初步

    .NET领域最为流行的IOC框架之一Autofac   一.前言 Autofac是.NET领域最为流行的IOC框架之一,微软的Orchad开源程序使用的就是Autofac,Nopcommerce开源程 ...

  3. Git使用总结 Asp.net生命周期与Http协议 托管代码与非托管代码的区别 通过IEnumerable接口遍历数据 依赖注入与控制反转 C#多线程——优先级 AutoFac容器初步 C#特性详解 C#特性详解 WPF 可触摸移动的ScrollViewer控件 .NET(C#)能开发出什么样的APP?盘点那些通过Smobiler开发的移动应用

    一,原理 首先,我们要明白Git是什么,它是一个管理工具或软件,用来管理什么的呢?当然是在软件开发过程中管理软件或者文件的不同版本的工具,一些作家也可以用这个管理自己创作的文本文件,由Linus开发的 ...

  4. IoC容器Autofac - Autofac + Asp.net MVC + EF Code First(转载)

    转载地址:http://www.cnblogs.com/JustRun1983/archive/2013/03/28/2981645.html  有修改 Autofac通过Controller默认构造 ...

  5. 转载 AutoFac常见用法总结

    第二节:框架前期准备篇之AutoFac常见用法总结   一. 说在前面的话 凡是大约工作在两年以上的朋友们,或多或少都会接触到一些框架搭建方面的知识,只要一谈到框架搭建这个问题或者最佳用法这个问题,势 ...

  6. ASP.NET Core依赖注入解读&使用Autofac替代实现【转载】

    ASP.NET Core依赖注入解读&使用Autofac替代实现 1. 前言 2. ASP.NET Core 中的DI方式 3. Autofac实现和自定义实现扩展方法 3.1 安装Autof ...

  7. 框架前期准备篇之AutoFac常见用法总结 转载

    框架前期准备篇之AutoFac常见用法总结 一. 说在前面的话 凡是大约工作在两年以上的朋友们,或多或少都会接触到一些框架搭建方面的知识,只要一谈到框架搭建这个问题或者最佳用法这个问题,势必会引起一点 ...

  8. Autofac学习之三种生命周期:InstancePerLifetimeScope、SingleInstance、InstancePerDependency 【转载】

    InstancePerLifetimeScope:同一个Lifetime生成的对象是同一个实例 SingleInstance:单例模式,每次调用,都会使用同一个实例化的对象:每次都用同一个对象: In ...

  9. AutoFac文档14(转载)

    目录 开始 Registering components 控制范围和生命周期 用模块结构化Autofac xml配置 与.net集成 深入理解Autofac 指导 关于 词汇表 激活事件 在compo ...

  10. AutoFac文档13(转载)

    目录 开始 Registering components 控制范围和生命周期 用模块结构化Autofac xml配置 与.net集成 深入理解Autofac 指导 关于 词汇表 属性注入 属性注入使用 ...

随机推荐

  1. base642photo

    /**     * pic to base64Str     * @param path 读取路径     * @return     */    public static String GetIm ...

  2. Ubuntu12.04 64bit版本下载Android源码完整教程

    首先去官网http://source.android.com/source/initializing.html可以看到完整的安装教程.不过一般情况下,按照这个教程是无法一步到位的,因为中途肯定会遇到很 ...

  3. Linux System Programming 学习笔记(一) 介绍

    1. Linux系统编程的三大基石:系统调用.C语言库.C编译器 系统调用:内核向用户级程序提供服务的唯一接口.在i386中,用户级程序执行软件中断指令 INT n 之后切换至内核空间 用户程序通过寄 ...

  4. GridView从行寻找到该控件,以及从该控件获知该行

    原文发布时间为:2008-08-01 -- 来源于本人的百度文章 [由搬家工具导入] GridView从行寻找到该控件: protected void Button3_Click(object sen ...

  5. VMware锁定文件失败开启模块diskearly的操作失败未能启动虚拟机

      删除虚拟机目录下的(如图中标明的就是D:\VMWorks\YeZiZxWeb这个目录)三个 *.lck文件夹,启动正常

  6. JS函数调用原理($.ajax原理)

    参考四种函数调用:http://www.cnblogs.com/qlqwjy/p/7660013.html http://www.cnblogs.com/qlqwjy/p/7660375.html 1 ...

  7. 【Visual Studio】error: /ZI”和“/Gy-”命令行选项不兼容(转)

    原文转自 http://bbs.100home.net/view/4206.html [问题说明]vc6项目用vs2015打开时遇到的错误 [解决方法]项目属性->c/c++->常规-&g ...

  8. HTML-在canvas画图中,图片的线上链接已配置允许跨域后,仍然出错提示跨域,怎么解决?

    这个问题我已经遇到了2次,第一次解决了后,第二次又遇到了,所以这次做个笔记,怕以后再次遇到 举例: 1.要实现的问题:我需要在canvas画布上画上我的微信头像 2.后台配置已经完成了允许我头像地址的 ...

  9. java中线程切换的开销

    思路: 开三个线程A,B,C 线程A不断的调用LockSupport.park()阻塞自己,一旦发现自己被唤醒,调用Thread.interrupted()清除interrupt标记位,同时增加自增计 ...

  10. Database | SQL

    Basic of MySQL 创建数据库: mysql> create database xxj; Query OK, row affected (0.00 sec) 列举数据库: mysql& ...