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 ...
随机推荐
- mysql执行计划简介
介绍 本篇主要通过汇总网上的大牛的知识,简单介绍一下如何使用mysql的执行计划,并根据执行计划判断如何优化和是否索引最优. 执行计划可显示估计查询语句执行计划,从中可以分析查询的执行情况是否最优,有 ...
- Web前端有价值的博客文章汇总
一.HTML 二.CSS 1.深入理解position和z-index属性 :https://www.cnblogs.com/zhuzhenwei918/p/6112034.html 2.BFC(清除 ...
- myeclipse设置环境(最实用的教程)
1. General --> Workspace --> UTF-82. General --> Editors --> Associations --> JSP --& ...
- ETL总结(扫盲版)
1.ETL名词解释 英文缩写 Extract-Transform-Load ,用来描述将数据从来源端经过抽取(extract).转换(transform).加载(load)至到目的端(一般指的是数 ...
- 关于字符latin capital letter sharp s "ß"( U+1E9E)显示的问题
今天测试产品时,遇到德语字符ß在网页上显示为”SS",查了一些相关资料发现这个字符一般用“ss"或"SS"取代. 需要注意,此字符与它的小写形式不同,小写字符l ...
- 关于Roll A Ball实例练习记录
学习中不段进步! 游戏思路:通过键盘控制白色小球,让它"捡起"柠黄色方块,捡起一个加1分,全部捡起游戏胜利! 游戏对象: Ground:绿色地面 player: 小球 Obsta ...
- js---BOW---页面打开方式,跳转方式 2017-03-24
BOM ( browse object model) 一.js页面的三种打开方式 1. window.open 格式: window.open("第一部分", "第二部 ...
- Online Judge(OJ)搭建——3、MVC架构
Model Model 层主要包含数据的类,这些数据一般是现实中的实体,所以,Model 层中类的定义常常和数据库 DDL 中的 create 语句类似. 通常数据库的表和类是一对一的关系,但是有的时 ...
- JavaScript之实例
<meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content=" ...
- python趣味 ——奇葩的全局形参
在c++,c#,js等语言中: 函数定义(参数) 函数体:参数修改 这里的参数修改都是仅限于这个函数体内的 python不知道是不是bug,我们这样写: def test(a=[]): a.appen ...