Autofac 简单示例
公司不用任何IOC,ORM框架,只好自己没事学学.
可能有些语言描述的不专业
希望能有点用
namespace Autofac { class Program { //声明一个容器 private static IContainer container; static void Main(string[] args) { #region 入门示例 1 { ////注册 Autofac 组件 //var builder = new ContainerBuilder(); ////注册 ConsoleOutput 组件, 提供 IOutput 服务 //builder.RegisterType<ConsoleOutput>().As<IOutput>(); ////注册 TodayWriter 组件, 提供 IDateWriter 服务 //builder.RegisterType<TodayWriter>().As<IDateWriter>(); ////创造一个容器 //container = builder.Build(); //using (ILifetimeScope scope = container.BeginLifetimeScope()) //{ // IDateWriter dateWriter = scope.Resolve<IDateWriter>(); // dateWriter.Write(); //} } #endregion #region 入门实例 2 { //var builder = new ContainerBuilder(); //builder.RegisterType<Person>(); //container = builder.Build(); //Person person; //using (var scope = container.BeginLifetimeScope()) //{ // person = scope.Resolve<Person>(); //} //person.Print(); } #endregion #region 自动选择合适的构造函数注入 { //var builder = new ContainerBuilder(); ////这里只注册了 ConsoleOutput ,没有注册 ILogger 类型的实例 //builder.RegisterType<ConsoleOutput>().As<IOutput>(); //builder.RegisterType<TodayWriter>().As<IDateWriter>(); //container = builder.Build(); //IDateWriter writer; //using (var scope = container.BeginLifetimeScope()) //{ // //当我们"决定"要一个 IDateWriter 接口类型的实例时,autofac会在容器里面寻找注册过的 IDateWriter 接口类型 // //当它找到 TodayWriter,并准备创建 TodayWriter 类型的实例时,发现有三个构造函数,分别接收 0个,1个,2个参数 // //这时候,autofac 会先尝试执行2个参数的构造函数,结果发现容器里面没有注册过 ILogger 接口类型的实现类 // //于是接着尝试执行1个参数的构造函数,当然,我们注册了 ConsoleOutput 类,这里肯定能找到,于是就用1个参数的构造函数创造了一个 TodayWriter 的实例 // //这点跟 Unity 是一样的. // writer = scope.Resolve<IDateWriter>(); //} //writer.Write(); } #endregion #region 手动指定构造函数注入 { //var builder = new ContainerBuilder(); //builder.RegisterType<ConsoleOutput>().As<IOutput>(); //builder.RegisterType<DataLogger>().As<ILogger>(); ////builder.RegisterType<TodayWriter>().As<IDateWriter>(); ////手动指定要执行的构造函数 //builder.RegisterType<TodayWriter>().As<IDateWriter>().UsingConstructor(typeof(IOutput)); //container = builder.Build(); //IDateWriter writer; //using (var scope = container.BeginLifetimeScope()) //{ // writer = scope.Resolve<IDateWriter>(); //} //writer.Write(); } #endregion #region 注册实例到容器中 { //var builder = new ContainerBuilder(); //var output = new ConsoleOutput(); ////当您执行此操作时,需要考虑的事情是 Autofac 自动处理注册组件的处理,您可能希望自己控制自己的生命周期,而不是让 Autofac 自动调用对您的对象的处理. ////在这种情况下,您需要使用 ExternallyOwned 方法注册该实例 //builder.RegisterInstance(output).As<IOutput>().ExternallyOwned(); //builder.RegisterType<TodayWriter>().As<IDateWriter>(); //container = builder.Build(); //IDateWriter writer; //using (var scope = container.BeginLifetimeScope()) //{ // writer = scope.Resolve<IDateWriter>(); //} //writer.Write(); } #endregion #region Lambda表达式 注入 { //var builder = new ContainerBuilder(); ////Register 为 Lambda表达式组件 注入 ////参数c是其中正在创建组件的组件上下文(IComponentContext对象) //builder.Register(c => new TodayWriter(c.Resolve<IOutput>())); ////RegisterType 为 反射组件 注入 ////后注册也没关系,真正生效是在 builder.Build() 创建容器的时候. //builder.RegisterType<ConsoleOutput>().As<IOutput>(); //container = builder.Build(); //IDateWriter writer; //using (var scope = container.BeginLifetimeScope()) //{ // writer = scope.Resolve<TodayWriter>(); //} //writer.Write(); } #endregion #region 注入泛型 { //var builder = new ContainerBuilder(); ////注册泛型 //builder.RegisterGeneric(typeof(MySql<>)).As(typeof(IDal<>)).InstancePerLifetimeScope(); ////我们假设要创建 泛型参数为 Person 的 Mysql<> 类的实例 //builder.RegisterType<Person>(); ////Person 需要 IDataWriter //builder.RegisterType<TodayWriter>().As<IDateWriter>(); ////TodayWriter 需要 IOutput //builder.RegisterType<ConsoleOutput>().As<IOutput>(); //container = builder.Build(); //IDal<Person> dal; //using (var scope = container.BeginLifetimeScope()) //{ // dal = scope.Resolve<IDal<Person>>(); //} //dal.Pint(); } #endregion #region 组件和服务 { //var builder = new ContainerBuilder(); //////注册组件时,必须告诉 Autofac ,注册的组件需要暴露哪些服务。 默认情况下,大多数注册只会将自己公开为注册类型 ////builder.RegisterType<Person>(); //////也可以 同时 暴露其他服务 ////builder.RegisterType<Person>().As<Human>(); ////这行代码是上面两行代码的简写 //builder.RegisterType<Person>().AsSelf().As<Human>(); ////也可以使用任意数量的服务来显示组件: //builder.RegisterType<Student>().As<ILogger>().As<IOutput>(); //container = builder.Build(); //ILogger loggerWriter; //IOutput outputWriter; //using (var scope = container.BeginLifetimeScope()) //{ // Human human = scope.Resolve<Human>(); // Person person = scope.Resolve<Person>(); // loggerWriter = scope.Resolve<ILogger>(); // outputWriter = scope.Resolve<IOutput>(); //} //loggerWriter.LoggerPrint(); //outputWriter.OutputPrint(); } #endregion #region 默认注册的组件 { //var builder = new ContainerBuilder(); ////这里注册了2个组件,ConsoleOutput 和 DataLogger ,他们公开了相同的服务 IWriter //builder.RegisterType<ConsoleOutput>().As<IWriter>(); ////这里会覆盖上面注册的组件 //builder.RegisterType<DataLogger>().As<IWriter>(); ////设置已经注册过的组件作为 服务 IWriter 的默认提供程序 ////新注册的组件不会再覆盖已注册的组件 ////也就是说,下面解析的时候,会创建 ConsoleOutput 的对象作为 IWriter 的实例 ////builder.RegisterType<DataLogger>().As<IWriter>().PreserveExistingDefaults(); //container = builder.Build(); //IWriter writer; //using (var scope = container.BeginLifetimeScope()) //{ // //Autofac 会默认使用最后注册的组件作为该服务的默认提供程序 // //也就是说,这里会默认创建 DataLogger 的对象作为 IWriter 的实例 // writer = scope.Resolve<IWriter>(); //} //writer.Write(); } #endregion #region 有条件的注册组件 { //var builder = new ContainerBuilder(); //builder.RegisterType<Person>().AsSelf().As<Human>(); ////如果还没有注册 Human 服务的组件,则注册 Student,提供 ILogger 服务 //builder.RegisterType<Student>().As<ILogger>().IfNotRegistered(typeof(Human)); ////如果还没有注册 Person 服务的组件,则注册 Student,提供 ILogger 服务 //builder.RegisterType<Student>().As<ILogger>().IfNotRegistered(typeof(Person)); ////如果还没有注册 ILogger 服务的组件,则注册 TodayWriter,提供 IDateWriter 服务 //builder.RegisterType<ConsoleOutput>().As<IOutput>().IfNotRegistered(typeof(ILogger)); //container = builder.Build(); //using (var scope = container.BeginLifetimeScope()) //{ // Human human = scope.Resolve<Human>(); // Person person = scope.Resolve<Person>(); // IOutput output = scope.Resolve<IOutput>(); // try // { // ILogger student = scope.Resolve<ILogger>(); // } // catch (Exception) // { // Console.WriteLine("还没有注册任何组件来提供 ILogger 服务"); // } //} } #endregion #region 带参数的注入 { //var builder = new ContainerBuilder(); ////注册组件时传入参数值的三种方式: ////builder.RegisterType<Person>().WithParameter(parameterName: "personName", parameterValue: "wjire"); ////builder.RegisterType<Person>().WithParameter(new TypedParameter(typeof(string), "wjire2")); ////builder.RegisterType<Person>().WithParameter(new ResolvedParameter((p, c) => p.ParameterType == typeof(string) && p.Name.Equals("personName"), (p, c) => "wjire3")); ////注册时不传,解析时传入参数值得方式: ////使用lambda表达式注册组件,不需要在注册时传入参数值,而是声明需要传入的参数值的名称 ////具体的参数值是在解析的时候传入. ////builder.Register((c, p) => new Person(p.Named<string>("parameterName"))); ////最简单的写法: //builder.RegisterType<Person>(); //container = builder.Build(); //using (var scope = container.BeginLifetimeScope()) //{ // //这种是在注册时就传入参数 // //Person person = scope.Resolve<Person>(); // //这是lambda表达式组件在解析时传入参数的方式 // //Person person = scope.Resolve<Person>(new NamedParameter("parameterName", "海尔兄弟")); // //这是最简单的方法 // //Person person = scope.Resolve<Person>(new ResolvedParameter((p, c) => p.ParameterType == typeof(string) && p.Name.Equals("personName"), (p, c) => "玫瑰花蕾")); // //Person person = scope.Resolve<Person>(new TypedParameter(typeof(string), "猫和老鼠")); // Person person = scope.Resolve<Person>(new NamedParameter("personName", "海尔兄弟")); // person.PrintWithParameter("refuge"); //} } #endregion #region 属性注入 { //var builder = new ContainerBuilder(); //builder.RegisterType<ConsoleOutput>().As<IOutput>(); ////反射组件方式: ////builder.RegisterType<TodayWriter>().As<IDateWriter>().PropertiesAutowired(); ////lambda表达式组件方式: //builder.Register(c => new TodayWriter { output = c.Resolve<IOutput>() }).As<IDateWriter>(); //container = builder.Build(); //using (var scope = container.BeginLifetimeScope()) //{ // //不会执行 含有 IOutput 类型的参数的构造函数 // IDateWriter writer = scope.Resolve<IDateWriter>(); // writer.Write(); //} } #endregion #region 方法注入 { //var builder = new ContainerBuilder(); //builder.RegisterType<ConsoleOutput>().As<IOutput>(); //builder.RegisterType<DataLogger>().As<ILogger>(); //// 使用 lambda 表达式组件,并在激活器中处理方法调用: //builder.Register(c => //{ // var result = new TodayWriter(); // var iOutput = c.Resolve<IOutput>(); // var iLogger = c.Resolve<ILogger>(); // result.SetPropertyValue(iOutput, iLogger); // return result; //}).As<IDateWriter>(); //container = builder.Build(); //using (var scope = container.BeginLifetimeScope()) //{ // IDateWriter writer = scope.Resolve<IDateWriter>(); // writer.Write(); //} } #endregion #region 注册程序集中的类型 { //var builder = new ContainerBuilder(); ////获取当前程序集 //var dataAccess = Assembly.GetExecutingAssembly(); ////注册程序集中所有具有无参数构造函数的公共具体类 //builder.RegisterAssemblyTypes(dataAccess); //container = builder.Build(); //using (var scope = container.BeginLifetimeScope()) //{ // Person p = scope.Resolve<Person>(); // Student s = scope.Resolve<Student>(); // try // { // Dog d = scope.Resolve<Dog>(); // } // catch (Exception) // { // Console.WriteLine($"{typeof(Dog)} 没有无参的构造函数"); // } // try // { // p.Print(); // } // catch (Exception) // { // Console.WriteLine("属性 dateWriter 为 null,因为它声明的是 IDateWriter 接口类型,不是具体类,所以没有被注册"); // } //} } { //var dataAccess = Assembly.GetExecutingAssembly(); //var builder = new ContainerBuilder(); ////注册所有接口类型 //builder.RegisterAssemblyTypes(dataAccess).AsImplementedInterfaces(); //container = builder.Build(); //using (var scope = container.BeginLifetimeScope()) //{ // //解析的时候,只会解析出一种实现类. // //具体解析出哪一种,暂时还没发现规律. // IWriter writer = scope.Resolve<IWriter>(); // writer.Write(); //} } { //var dataAccess = Assembly.GetExecutingAssembly(); //var builder = new ContainerBuilder(); ////注册所有 ILogger 接口类型 //builder.RegisterAssemblyTypes(dataAccess).As<ILogger>(); //container = builder.Build(); //using (var scope = container.BeginLifetimeScope()) //{ // ILogger writer = scope.Resolve<ILogger>(); // writer.Write(); // try // { // Person p = scope.Resolve<Person>(); // } // catch (Exception) // { // Console.WriteLine($"{typeof(Person)} 没有注册"); // } //} } #endregion #region 过滤程序集中的类型 { //var dataAccess = Assembly.GetExecutingAssembly(); //var builder = new ContainerBuilder(); ////利用谓词过滤类型 ////builder.RegisterAssemblyTypes(dataAccess).Where(w => w.Name.StartsWith("P")); ////排除 Person 类型 //builder.RegisterAssemblyTypes(dataAccess).Except<Person>(); //container = builder.Build(); //using (var scope = container.BeginLifetimeScope()) //{ // try // { // Person p = scope.Resolve<Person>(); // } // catch (Exception) // { // Console.WriteLine($"{typeof(Person)} 没有注册"); // } // try // { // Student s = scope.Resolve<Student>(); // } // catch (Exception) // { // Console.WriteLine($"{typeof(Student).Name} 不是以 'P' 开头"); // } //} } #endregion #region 模块扫描 #endregion #region 实例范围 #region 每次解析都创建一个新的实例 //{ // var builder = new ContainerBuilder(); // builder.RegisterType<TodayWriter>().As<IDateWriter>(); // container = builder.Build(); // using (var scope = container.BeginLifetimeScope()) // { // //每次循环都将创建一个新的实例 // for (var i = 0; i < 100; i++) // { // IDateWriter writer = scope.Resolve<IDateWriter>(); // } // } //} #endregion #region 在当前生命周期范围内单例,不包含嵌套的生命周期范围(嵌套的算新的) //{ // var builder = new ContainerBuilder(); // //在当前生命周期范围内是单例,构造函数只会执行一次,局部单例 New scope = new instance // builder.RegisterType<TodayWriter>().As<IDateWriter>().InstancePerLifetimeScope(); // container = builder.Build(); // using (var scope1 = container.BeginLifetimeScope()) // { // for (var i = 0; i < 100; i++) // { // //当前生命周期范围内只创建一次对象 // IDateWriter writer1 = scope1.Resolve<IDateWriter>(); // //尽管每次循环都是在 scope1 生命周期范围内嵌套的生命周期范围 // //但每次循环,下面依然会创建一个新的对象 // using (var scope2 = scope1.BeginLifetimeScope()) // { // IDateWriter writer2 = scope2.Resolve<IDateWriter>(); // } // } // } //} #endregion #region 在指定的生命周期范围内单例,注意与上面的区别 //{ // var builder = new ContainerBuilder(); // builder.RegisterType<TodayWriter>().As<IDateWriter>().InstancePerMatchingLifetimeScope("myScope"); // container = builder.Build(); // using (var scope1 = container.BeginLifetimeScope("myScope")) // { // for (var i = 0; i < 100; i++) // { // IDateWriter writer1 = scope1.Resolve<IDateWriter>(); // //尽管每次都嵌套了一个新的生命周期范围 // //但它依然属于名为"myScope"的生命周期范围 // //因为它是嵌套在"myScope"的生命周期范围内的 // //所以是单例 // using (var scope2 = scope1.BeginLifetimeScope()) // { // IDateWriter writer2 = scope2.Resolve<IDateWriter>(); // } // } // } // //但是下面会创建一个新的实例 // //因为它是另外一个名叫"myScope"的生命周期范围 // using (var scope1 = container.BeginLifetimeScope("myScope")) // { // for (var i = 0; i < 100; i++) // { // IDateWriter writer1 = scope1.Resolve<IDateWriter>(); // using (var scope2 = scope1.BeginLifetimeScope()) // { // IDateWriter writer2 = scope2.Resolve<IDateWriter>(); // } // } // } //} #endregion #region 终生单例 //{ // var builder = new ContainerBuilder(); // //终生单例,构造函数只会执行一次 // builder.RegisterType<TodayWriter>().As<IDateWriter>().SingleInstance(); // container = builder.Build(); // using (var scope1 = container.BeginLifetimeScope()) // { // for (var i = 0; i < 100; i++) // { // IDateWriter writer1 = scope1.Resolve<IDateWriter>(); // using (var scope2 = container.BeginLifetimeScope()) // { // IDateWriter writer2 = scope2.Resolve<IDateWriter>(); // } // } // } //} #endregion #region 每次请求单例 { //var builder = new ContainerBuilder(); //Asp.Net MVC中才能使用 //builder.RegisterType<TodayWriter>().As<IDateWriter>().InstancePerRequest(); } #endregion #region 依赖于某个组件的实例 //{ // var builder = new ContainerBuilder(); // builder.RegisterType<TodayWriter>().As<IDateWriter>().InstancePerOwned<Person>(); // builder.RegisterType<Person>().UsingConstructor(typeof(IDateWriter)); // container = builder.Build(); // using (var scope = container.BeginLifetimeScope()) // { // var owned = scope.Resolve<Owned<Person>>(); // Person p = owned.Value; // try // { // IDateWriter writer = scope.Resolve<IDateWriter>(); // } // catch (Exception) // { // Console.WriteLine("不能单独解析 IDateWriter ,因为它的生命周期范围只存在于解析 Person 组件时"); // } // owned.Dispose(); // } //} #endregion #region 线程范围,还没有深入的理解,目前看来,本质就是当前生命周期范围内的单例 { var builder = new ContainerBuilder(); builder.RegisterType<TodayWriter>().As<IDateWriter>().InstancePerLifetimeScope(); container = builder.Build(); Task.Run(() => { using (var scope = container.BeginLifetimeScope()) { IDateWriter thisThreadInstance = scope.Resolve<IDateWriter>(); } }); Task.Run(() => { using (var scope = container.BeginLifetimeScope()) { IDateWriter thisThreadInstance = scope.Resolve<IDateWriter>(); } }); } #endregion #endregion Console.ReadKey(); } } }
转网上一段总结:
1.依赖注入的目的是为了解耦。
2.不依赖于具体类,而依赖抽象类或者接口,这叫依赖倒置。
3.控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器
Autofac 简单示例的更多相关文章
- ioc autofac简单示例
1.winform用法: nuget安装autofac public interface ILog { bool Log(string msg); } public class TXTLogger : ...
- 基于.NET CORE微服务框架 -surging的介绍和简单示例 (开源)
一.前言 至今为止编程开发已经11个年头,从 VB6.0,ASP时代到ASP.NET再到MVC, 从中见证了.NET技术发展,从无畏无知的懵懂少年,到现在的中年大叔,从中的酸甜苦辣也只有本人自知.随着 ...
- AutoFac简单入门
AutoFac是.net程序下一个非常灵活易用,且功能强大的DI框架,本文这里简单的介绍一下使用方法. 安装: Install-Package Autofac 简单的示例: static void M ...
- Linux下的C Socket编程 -- server端的简单示例
Linux下的C Socket编程(三) server端的简单示例 经过前面的client端的学习,我们已经知道了如何创建socket,所以接下来就是去绑定他到具体的一个端口上面去. 绑定socket ...
- C# 构建XML(简单示例)
C# 构建XML的简单示例: var pars = new Dictionary<string, string> { {"url","https://www. ...
- 根据juery CSS点击一个标签弹出一个遮罩层的简单示例
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- ACEXML解析XML文件——简单示例程序
掌握了ACMXML库解析XML文件的方法后,下面来实现一个比较完整的程序. 定义基本结构 xml文件格式如下 <?xml version="1.0"?> <roo ...
- demo工程的清单文件及activity中api代码简单示例
第一步注册一个账户,并创建一个应用.获取app ID与 app Key. 第二步下载sdk 第三步新建工程,修改清单文件,导入相关的sdk文件及调用相应的api搞定. 3.1 修改清单文件,主要是加入 ...
- spring-servlet.xml简单示例
spring-servlet.xml简单示例 某个项目中的spring-servlet.xml 记下来以后研究用 <!-- springMVC简单配置 --> <?xml versi ...
随机推荐
- 使用netflix Zuul 代理你的微服务
构建 "微服务" 时的一个常见挑战是为系统的使用者提供一个统一的接口.您的服务被分割成一个个积木式的小程序,事实上这些细节本不应该对用户可见. 为了解决这个问题, Netflix ...
- 杭电oj-1002-A+B Problem
Problem Description I have a very simple problem for you. Given two integers A and B, your job is to ...
- 直播-srs起步
srs简介 https://github.com/ossrs/srs/wiki/v2_CN_Home 原料 CentOS Linux release 7.2.1511 (Core) ffmpe ...
- [转]【安卓笔记】AsyncTask源码剖析
[转][安卓笔记]AsyncTask源码剖析 http://blog.csdn.net/chdjj/article/details/39122547 前言: 初学AsyncTask时,就想研究下它的实 ...
- Lintcode247 Segment Tree Query II solution 题解
[题目描述] For an array, we can build a Segment Tree for it, each node stores an extra attribute count t ...
- Python的Argparse模块是什么?(未完)
近日在阅读代码的过程中遇到了Argparse模块,记得前段时间已经看了,可是过了两周现在又忘了, 看来写代码一定要钻研到底搞清楚其中原委才行,本文主要参考Python3.6系列官方文档 ...
- WordPress制作一个首字母排序的标签页面
很早就想制作这样一个页面了,废话不多说, 先看看效果:传送门 在网上找了很多的代码,试了很久,修改了一些代码,最终就达到了现在的效果. 实现方法:(里面增加了缓存功能,打开页面更快,对数据进行了缓存, ...
- ASP.NET Core Web 支付功能接入 微信-扫码支付篇
这篇文章将介绍ASP.NET Core中使用 开源项目 Payment,实现接入微信-扫码支付及异步通知功能. 开发环境:Win 10 x64.VS2017 15.6.4..NET Core SDK ...
- spring Boot+spring Cloud实现微服务详细教程第二篇
上一篇文章已经说明了一下,关于spring boot创建maven项目的简单步骤,相信很多熟悉Maven+Eclipse作为开发常用工具的朋友们都一目了然,这篇文章主要讲解一下,构建spring bo ...
- USB Audio设计与实现
1 前言 本文将基于STM32F4 Discovery板,从零开始设计并实现一个USB Audio的例子. 2 设计构思 所谓的USB AUDIO就是制作一个盒子,这个盒子可以通过USB连接到PC,P ...