本次主要学习一下Autofac中实现类型注册的几种方式,这里并不打算一开始就从基于接口开发的服务关联切入,而是先从一个简单的类型注册来学起,虽然实际开发中可能不会这么做,但是个人感觉从这里学起理解能能更加深刻

Autofac使用流程

  • 按照Ioc(控制反转)的思想构建你的应用
  • 添加Autofac引用
  • 创建ContainerBuilder
  • 注册组件
  • 创建容器,将其保存以备后续使用
  • 应用程序运行阶段
  • 从容器中创建一个生命周期
  • 在此生命周期作用域内解析组件实例

nuget添加Autofac引用

测试代码

这里提供一个很简单的类作为测试

class SqlDal
{public void Add(){Console.WriteLine("向数据库写入一条数据");}
}

创建容器

所有的Ioc框架都是类似的,它们的目的都是将类的实例化和调用解耦,调用者不再直接创建被调用者的实例,而是交由容器创建,只是在实现上有各自不同的方式

var builder = new ContainerBuilder();

普通注册

泛型注册:RegisterType<T>()

注册的类型必须在当前项目或被当前项目引用,因为使用泛型,必须类型明确

//将SqlDal类注册到容器中
builder.RegisterType<SqlDal>();

//通过Resolve()方法获取注册类型的实例,不推荐这种方式获取,这里的代码只作为测试
using (var container = builder.Build())
{               var sqlDal = container.Resolve<SqlDal>();sqlDal.Add();
}

通过Type对象进行注册:RegisterType(Type)

被注册的类型可以不是被直接引用,但类型所在的程序集必须被加载,这种注册方式在有插件或类似需要动态加载程序集的情况下使用,通过扫描程序集,获取一些满足指定条件的类型,来进行注册。

通过在项目中引用CSharp.Tests.Model实现

Assembly assembly = Assembly.Load("CSharp.Tests.Model");
var type = assembly.GetType("CSharp.Tests.Model.AutofacTestModel");
builder.RegisterType(type);
using (var container = builder.Build())
{var model = container.Resolve<AutofacTestModel>();Console.WriteLine(model.SayHello());
}

TODO:将dll拷贝到bin目录下不用引用dll也可以实现注册,但是如何将类型作为Resolve<T>泛型类型参数暂时不知道

lambda表达式注册

之前的方式都是通过类型进行直接注册的,这种注册方式,在获取时,会直接通过构造函数new出对象,不会做更多的操作。有时我们希望能够在获取对象时能够自动的做更多的事情时,我们可以通过lambda注册来解决,在lambda表达式中可以做很多事,包括一些属性注入、方法注入、条件判断等等

class SqlDal
{public string Str { get; set; }public void Add(){Console.WriteLine("向SqlServer数据库写入一条数据,Str={0}", Str);}
}

builder.Register(type =>
{//通过lambda表达式注册时添加属性值var sqlDal = new SqlDal();         sqlDal.Str = "Test";return sqlDal;
});

实例注册

通过RegisterInstance进行实例注册,进行实例注册时,需要注意,实例注册可以作为一种单例注册的方式,也就是在后面通过Autofac获取SqlDal对象时,获取到的是注册时的那个对象。并且,如果一个在某处修改了该对象,其他地方再获取时,获取到的就是修改后的对象

builder.RegisterInstance(new SqlDal());
using (var container = builder.Build())
{var sqlDal = container.Resolve<SqlDal>();sqlDal.Add();
}

泛型注册

通过RegisterGeneric() 这个方法实现泛型注册,在容器中可以创建出泛型的具体对象

builder.RegisterGeneric(typeof(List<>)).As(typeof(IList<>)).InstancePerLifetimeScope();
using (IContainer container = builder.Build())
{var ListString = container.Resolve<IList<string>>();
}

Module注册

在日常开发中,可能不同开发会负责不同的模块进行单独开发。在开发过程中,不同模块不同开发可能都有自己的类型需要注册到autofac中,但是如果每个人在注册时,都去修改一个指定地方的代码,这在进行代码合并时,是令人痛苦的。更好的方式是,每个开发不同的模块都有自己指定的类型注册区域,这样,在代码合并时,会减少很多代码冲突

class SqlModule : Autofac.Module
{protected override void Load(ContainerBuilder builder){builder.RegisterType<SqlDal>();}
}
class MySqlModule : Autofac.Module
{protected override void Load(ContainerBuilder builder){builder.RegisterType<MySqlDal>();}
}

builder.RegisterModule<SqlModule>();
builder.RegisterModule<MySqlModule>();
using (var container = builder.Build())
{var sqldal = container.Resolve<SqlDal>();sqldal.Add();var mysqldal = container.Resolve<MySqlDal>();mysqldal.Add();
}

上述代码中,有两个继承自Module类的类:SqlModule、MySqlModule,这两个类型重写了父类的Load方法,并在load方法中,分别注册了SqlDal与MySqlDal类型。然后在主程序中,通过RegisterModule对Module进行注册。

通过这种方式,不同的开发就可以各自创建一个类继承自Module,然后重写Load方法,在Load方法进行自己的类型注册,最后再进行Module的统一注册(这里还可以通过自定义实现了IModule接口的类型,然后在RegisterModule时传入来达到同样的效果并且功能也更多)

默认的注册

如果一个类型被多次注册,以最后注册的为准。通过使用PreserveExistingDefaults() 修饰符,可以指定某个注册为非默认值。

批量注册、程序集注册

上面的例子中都是将单个类型注册到容器中,而在实际开发中可能存在多个类型需要注册,难道要每个类型挨个注册吗?Autofac中为这种情况提供了程序集注册的方式

程序集批量注册

类型注册中提到了通过扫描程序集,来获取部分类型进行注册。Autofac对此提供了一个方便的方式,可以直接通过程序集来筛选类型注册

//获取当前应用程序加载程序集(C/S应用中使用)
var assembly = Assembly.GetExecutingAssembly();
//注册所有程序集类定义的非静态类型
builder.RegisterAssemblyTypes(assembly);

 程序集过滤后批量注册

上面的方式达到了批量的效果,但是通常并不需要把所有的类型都进行注册,所以Autofac提供了几种过滤方式

builder.RegisterAssemblyTypes(assembly).Where(type => type.Namespace.Equals("CSharp.Tests.框架学习"));

 排除指定类型的注册

使用Except排除指定类型的注册

builder.RegisterAssemblyTypes(assembly).Where(type => type.Namespace.Contains("CSharp.Tests")).Except<CSharp.Tests.设计思想.SqlDal>();

程序集Module注册

Module注册,为多人开发提供了一种方便的注册方式,但是也可以发现,这种方式,还是会需要手动注册Module,如果Module过多,Module注册代码也会显得多而杂,当然,可以通过人工管理来控制Module的量。但是Autofac还提供了一种更方便的方式,并且,对于类似Orchard的模块开发(子模块与主模块无引用关系,通过程序集加载方式来加载子模块)或是插件开发,我们没办法通过Registerodule来注册无直接引用关系的Module

var assembly = Assembly.GetExecutingAssembly();
//注册assembly程序集中所有实现了IModule接口的类型(多层继承也算),这样只需要取出所有程序集,然后通过RegisterAssemblyModules进行一次性注册,就可以自动注册所有Module了
builder.RegisterAssemblyModules(assembly);
builder.RegisterAssemblyModules<SqlModule>(assembly);//指定泛型类型只注册assembly程序集中继承自SqlModule的Module 

被注册的类型需要在指定类的命名空间中

var assembly = Assembly.GetExecutingAssembly();builder.RegisterAssemblyTypes(assembly).InNamespaceOf<AutofacTest>();

转载于:https://www.cnblogs.com/GnailGnepGnaw/p/10747541.html

Autofac之类型注册相关推荐

  1. 关于XLL加载项动态加载、卸载的演示及XLL函数自定义类型注册的演示

    1.在XLL中,把函数定义成不同的类型,在Excel中的实际效果也不同,具体如下: pxMacroType value                                          ...

  2. [Abp vNext 源码分析] - 3. 依赖注入与拦截器

    一.简要说明 ABP vNext 框架在使用依赖注入服务的时候,是直接使用的微软提供的 Microsoft.Extensions.DependencyInjection 包.这里与原来的 ABP 框架 ...

  3. Autofac注册组件(3)

    Autofac注册组件 官网地址 一.扫描类型 1.过滤类型(Filtering Types) 2.指定服务(Specifying Services) 二.net core 3.x使用Autofac以 ...

  4. VSCode注册关联自定义类型文件

    打开你要注册的文件类型文件[本文中用 ".txt"到".lua"演示] 在VSCode窗口右下角有当前文件类型"Plain Text" 是可 ...

  5. C#中读取“已注册的文件类型”的图标及读取指定文件图标的方法 (转)

    using System; using System.IO; using System.Drawing; using Microsoft.Win32; using System.Runtime.Int ...

  6. .Net Core DI,如何在程序集中注册所有现有的可分配类型

    介绍 .Net Core带有自己的依赖性注入容器,.Net Core 3.0表明.Net Core DI既可靠又高效.它仍然有一些缺点.有许多扩展程序可解决这些缺点,它们提供了极好的机会.基本上,.N ...

  7. Autofac 组件、服务、自动装配 《第二篇》

    一.组件 创建出来的对象需要从组件中来获取,组件的创建有如下4种(延续第一篇的Demo,仅仅变动所贴出的代码)方式: 1.类型创建RegisterType AutoFac能够通过反射检查一个类型,选择 ...

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

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

  9. 用Scrutor来简化ASP.NET Core的DI注册

    目录 背景 Scrutor简介 Scrutor的简单使用 注册接口的实现类 注册类自身 重复注册处理策略 总结 相关文章 背景 在我们编写ASP.NET Core代码的时候,总是离不开依赖注入这东西. ...

最新文章

  1. python常用内置函数可以操作字符串_Python常用内置函数(二)
  2. C#中怎样跨窗体调用事件-从事件订阅实例入手
  3. VS中调试时不能关联源代码问题
  4. Spring Cloud Feign注意点
  5. tf.reduce_sum()方法深度解析
  6. 【OpenCV 例程200篇】63. 图像锐化——Laplacian 算子
  7. 使用PostSharp进行AOP框架设计:一个简单的原型
  8. java mapreduce_通过简单的Word Count讲解MapReduce原理以及Java实现
  9. 【数据预测】基于matlab鸟群算法优化BP神经网络数据预测【含Matlab源码 1772期】
  10. 【光学】Matlab实现色散曲线拟合
  11. 基于Nextcloud,挂载Google drive,搭建Aria2+AriaNg,实现在线下载BT磁链/在线观看/全功能文件管理/无限容量云盘
  12. Bootcamp提示该USB驱动器无法使用
  13. 微软应用商店Ubuntu 20.04 LTS打开0x8007019e错误解决
  14. 怎样将tiff格式转成jpg或png?
  15. 各种品牌电脑U盘启动快捷键
  16. 翁恺c语言程序设计入门期末,程序设计入门-C语言 翁恺.doc
  17. 2021寒假每日一题《数独检查》
  18. 20211104:Excel今天距某个日期后90天还剩多少天
  19. 网页制作篇(智慧树网站马红老师)-基础知识总结1(标记篇)
  20. .NET基础-11-ArrayList|Hashtable|File文件操作|Dircetioy文件夹操作|Path路径操作

热门文章

  1. Linux从删库到跑路的命令,使用 trash-cli 跳出 rm 命令从删库到跑路的深渊
  2. Qt 做个简易的计算器,加减乘除平方开根
  3. linux下使用代理加速下载方案集合
  4. Photoshop CC 2017 for Photographers: New Features Photoshop CC 2017为摄影师准备的新特性 Lynda课程中文字幕
  5. nn.Parameter()
  6. LeetCode 链表 队列 栈的问题
  7. 揭秘团队业绩不好的原因
  8. Castor学习笔记(一)
  9. 开源免费的舆情系统的架构
  10. 淘宝/天猫如何获取sku API接口,item_sku - 获取sku详细信息