using Autofac;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace ConsoleApp2.test1
{
public class Class8
{
//原文:
//https://www.cnblogs.com/TianFang/p/9005057.html
//https://www.cnblogs.com/dunitian/p/5693193.html //原文:
//https://blog.csdn.net/huwei2003/article/details/40022011
//系统 可方便的替换 日志类
//依赖接口,日志的实例化 不直接写在依赖类中,而是放在构造函数的参数中。目的:谁调用谁实现。然后再借助ioc自动实例化注入到构造函数中 //现在我们使用Ioc容器--Autofac改进上面的代码,
//目标是消除代码中的new语句,把实例化类的控制权转移到别的地方,
//这个地方通常会在一个程序加载时只执行一次的全局方法中 /* 原文:https://www.cnblogs.com/jesse2013/p/di-in-aspnetcore.html 容器 管理 依赖 容器负责两件事情:
1、绑定服务与实例之间的关系(注册)
2、获取实例,并对实例进行管理(实例的创建与销毁) 实例的生命周期:
Transient: 每一次GetService都会创建一个新的实例
Scoped: 在同一个Scope内只初始化一个实例 ,可以理解为( 每一个request级别只创建一个实例,同一个http request会在一个 scope内)
Singleton :整个应用程序生命周期以内只创建一个实例 */ //一.基本步骤:
// 1.设计适合控制反转(IoC)的应用程序
// 2.给应用程序Autofac 引用.
// 3.注册组件.
// 4.创建一个Container以备后用.
// 5.从Container创建一个 lifetime scope .
// 6.使用这个Lifetime Scope 来解析组件的实例. public void test1()
{
var builder = new ContainerBuilder();
builder.RegisterType<ConsoleLogger>().As<ILogger>(); var container = builder.Build();
var logger = container.Resolve<ILogger>(); logger.SayHello();
} public void test2()
{
ITestBLL testBLL = Container.Resolve<ITestBLL>();
var Name = testBLL.GetName();
Console.WriteLine(Name);
} public void test3()
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<LcService>().As<ILcService>().InstancePerDependency(); var container = builder.Build();
var lifetimeScope = container.BeginLifetimeScope();
ILcService service = lifetimeScope.Resolve<ILcService>();
} //这种写法 一个不好地方 在很多个地方都会实例化Log
//问题:控制是反转了,但是依赖增多了
public void test4()
{
ILog log = new Log();
var productService = new ProductService3(log);
productService.SayHello();
} //依赖由ioc框架自动管理
public void test5()
{
ContainerBuilder builder = new ContainerBuilder(); //替换系统的日志类
//builder.RegisterType<Log>().As<ILog>();
//builder.RegisterType<TxtLog>().As<ILog>();
builder.RegisterType<DbLog>().As<ILog>(); builder.RegisterType<ProductService3>();
IContainer container = builder.Build();
var productService = container.Resolve<ProductService3>();
productService.SayHello();
} //实例的创建方式(实例的生命周期):
// InstancePerDependency:在其他容器中也称作瞬态或者工厂,使用Per Dependency作用域,服务对于每次请求都会返回新的实例.
// SingleInstance:单例
// InstancePerLifetimeScope:每一个lifetime内, 生成的对象都是同一个实例 //不同作用域,生成不同对象
//InstancePerLifetimeScope:每一个lifetime内, 生成的对象都是同一个实例
public void test7()
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<TestInstanceType>().InstancePerLifetimeScope();
IContainer container = builder.Build(); //结论: 实例1 != 实例2
// 不同作用域,创建的实例不一样。
// 可用于:不同request,生成不同对象。同一request,生成同一个对象。
using (var scope = container.BeginLifetimeScope())
{
//实例1:这个范围内只存在一个
var model = scope.Resolve<TestInstanceType>();
Console.WriteLine($"实例1:{model.Name}");
}
using (var scope = container.BeginLifetimeScope())
{
//实例2:这个范围内只存在一个
var model = scope.Resolve<TestInstanceType>();
Console.WriteLine($"实例2:{model.Name}");
} //结论: 实例3 == 实例4
var scope3 = container.BeginLifetimeScope();
var model3 = scope3.Resolve<TestInstanceType>();
Console.WriteLine($"实例3:{model3.Name}"); var scope4 = container.BeginLifetimeScope();
var model4 = scope4.Resolve<TestInstanceType>();
Console.WriteLine($"实例4:{model3.Name}");
} //每一次 都生成不同对象
//InstancePerDependency:在其他容器中也称作瞬态或者工厂,使用Per Dependency作用域,服务对于每次请求都会返回新的实例.
public void test8()
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<TestInstanceType>().InstancePerDependency();
IContainer container = builder.Build(); for (int i = ; i < ; i++)
{
var model = container.Resolve<TestInstanceType>();
Console.WriteLine($"实例1:{model.Name}");
}
} //单例
//SingleInstance:单例
public void test9()
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<TestInstanceType>().SingleInstance();
IContainer container = builder.Build(); for (int i = ; i < ; i++)
{
var model = container.Resolve<TestInstanceType>();
Console.WriteLine($"实例{i}:{model.Name}");
} using (var scope = container.BeginLifetimeScope())
{
var model = scope.Resolve<TestInstanceType>();
Console.WriteLine($"实例4:{model.Name}");
}
} } //测试实例类型
public class TestInstanceType
{
public string Name { get; set; }
public TestInstanceType()
{
Name = Guid.NewGuid().ToString();
}
public string GetName()
{
return Name;
}
} //1、直接依赖Log类
// 系统更换Log类比较麻烦,因为每个类都依赖具体的实现类
public class ProductService1
{
private Log _log; public ProductService1()
{
_log = new Log();
} public void SayHello()
{
_log.Write();
}
} //2、依赖接口ILog
// 方法的调用依赖接口ILog。以前是依赖具体实现类Log,换成依赖接口类ILog,这样在构造函数中可以更换其它的实现类
// 在构造函数中 强依赖 ILog的具体实现
public class ProductService2
{
private ILog _log; public ProductService2()
{
_log = new Log();
} public void SayHello()
{
_log.Write();
}
} //3、强依赖的地方 变成了 谁调用谁实现
// 这样就可以 不再类ProductService3的内部 具体实现ILog,把实现的地方,转移到类的外部
public class ProductService3
{
private ILog _log; public ProductService3(ILog _log)
{
this._log = _log;
} public void SayHello()
{
_log.Write();
}
} //日志接口
public interface ILog
{
void Write();
}
//日志类1 实现 日志接口
public class Log : ILog
{
public void Write()
{
Console.Write("Log");
}
}
//日志类2 实现 日志接口
public class TxtLog : ILog
{
void ILog.Write()
{
Console.Write("TxtLog");
}
}
//日志类3 实现 日志接口
public class DbLog : ILog
{
void ILog.Write()
{
Console.Write("DbLog");
}
} public interface ILcService
{
string ServiceName { get; }
}
public class LcService : ILcService
{
public string ServiceName
{
get;
set;
}
} /// <summary>
/// Autofac IOC类
/// </summary>
public class Container
{
/// <summary>
/// IOC 容器
/// </summary>
public static IContainer container = null;
public static T Resolve<T>()
{
try
{
if (container == null)
{
Initialise();
}
}
catch (Exception ex)
{
throw new Exception("IOC实例化出错!" + ex.Message);
} return container.Resolve<T>();
} /// <summary>
/// 初始化
/// </summary>
public static void Initialise()
{
var builder = new ContainerBuilder(); // InstancePerLifetimeScope 同一个Lifetime生成的对象是同一个实例
// SingleInstance 单例模式,每次调用,都会使用同一个实例化的对象;每次都用同一个对象
// InstancePerDependency 默认模式,每次调用,都会重新实例化对象;每次请求都创建一个新的对象 //格式:builder.RegisterType<xxxx>().As<Ixxxx>().InstancePerLifetimeScope();
builder.RegisterType<TestBLL>().As<ITestBLL>().InstancePerLifetimeScope(); container = builder.Build();
}
} public interface ITestBLL
{
string GetName();
}
public class TestBLL : ITestBLL
{
public string GetName()
{
return "我为NET狂-官方群① 238575862";
}
} public interface ILogger
{
void SayHello();
}
public class ConsoleLogger : ILogger
{
public void SayHello()
{
Console.WriteLine("");
}
} }

开源项目 08 IOC Autofac的更多相关文章

  1. 从0开始学习 GitHub 系列之「08.如何发现优秀的开源项目」

    之前发过一系列有关 GitHub 的文章,有同学问了,GitHub 我大概了解了,Git 也差不多会使用了,但是 还是搞不清 GitHub 如何帮助我的工作,怎么提升我的工作效率? 问到点子上了,Gi ...

  2. 收集常用的.net开源项目

    Json.NET http://json.codeplex.com/ Json.NET是一个读写Json效率比较高的.Net框架.Json.Net 使得在.Net环境下使用Json更加简单.通过Lin ...

  3. .Net 开源项目资源大全

    伯乐在线已在 GitHub 上发起「DotNet 资源大全中文版」的整理.欢迎扩散.欢迎加入. https://github.com/jobbole/awesome-dotnet-cn (注:下面用 ...

  4. C# 开源项目一

    商业协作和项目管理平台-TeamLab 网络视频会议软件-VMukti 驰骋工作流程引擎-ccflow [免费]正则表达式测试工具-Regex-Tester Windows-Phone-7-SDK E ...

  5. Java开源项目(备查)

    转自:http://www.blogjava.net/Carter0618/archive/2008/08/11/221222.html Spring Framework  [Java开源 J2EE框 ...

  6. 收集经常使用的.net开源项目

    Json.NET http://json.codeplex.com/ Json.Net是一个读写Json效率比較高的.Net框架.Json.Net 使得在.Net环境下使用Json更加简单.通过Lin ...

  7. C# 网上收集的一些所谓的开源项目

    C#开源 商业协作和项目管理平台-TeamLab 网络视频会议软件-VMukti 驰骋工作流程引擎-ccflow [免费]正则表达式测试工具-Regex-Tester Windows-Phone-7- ...

  8. 常用的.net开源项目

    Json.NET http://json.codeplex.com/ Json.Net 是一个读写Json效率比较高的.Net框架.Json.Net 使得在.Net环境下使用Json更加简单.通过Li ...

  9. 【Android 应用开发】GitHub 优秀的 Android 开源项目

    原文地址为http://www.trinea.cn/android/android-open-source-projects-view/,作者Trinea 主要介绍那些不错个性化的View,包括Lis ...

随机推荐

  1. 安装Nexus时报Error occurred shutting down framework: java.lang.NumberFormatException: null

    Error occurred shutting down framework: java.lang.NumberFormatException: null 原因 :路径中有中文

  2. 刨根究底字符编码之十六——Windows记事本的诡异怪事:微软为什么跟联通有仇?(没有BOM,所以被误判为UTF8。“联通”两个汉字的GB内码,其第一第二个字节的起始部分分别是“110”和“10”,,第三第四个字节也分别是“110”和“10”)

    1. 当用一个软件(比如Windows记事本或Notepad++)打开一个文本文件时,它要做的第一件事是确定这个文本文件究竟是使用哪种编码方式保存的,以便于该软件对其正确解码,否则将显示为乱码. 一般 ...

  3. Go ---- defer 和 return 执行的先后顺序

    Go 中 defer 和 return 执行的先后顺序 多个defer的执行顺序为“后进先出”: defer.return.返回值三者的执行逻辑应该是:return最先执行,return负责将结果写入 ...

  4. JAVA-AbstractQueuedSynchronizer-AQS

    import lombok.extern.slf4j.Slf4j; import java.util.concurrent.CountDownLatch; import java.util.concu ...

  5. netcore访问本地磁盘

    public void ConfigureServices(IServiceCollection services) { services.AddDirectoryBrowser(); }public ...

  6. 资料汇总_Gitlab使用记录

    1)搭建并配置本地GitLab服务器教程 https://www.cnblogs.com/yinkemeng/p/10144782.html 2)记一次为gitlab启用CI的过程 https://w ...

  7. selenium中元素操作之简单的鼠标、键盘操作(三)

    1.鼠标操作导入类:ActionChains --鼠标的操作形成一连串的动作链,由selenium的ActionChains类来完成模拟鼠标操作手表操作的过程:1.鼠标的操作,先放到一个列表中2.利用 ...

  8. 独热编码(One-Hot)的理解

    https://www.imooc.com/article/35900 参考上面大神的原文,说的非常透彻.非常便于理解.感谢 感谢 自己做个小笔记,便于自己学习 特征值是离散的,无序的. 如: 性别特 ...

  9. 【高并发解决方案】8、Nginx/LVS/HAProxy负载均衡软件的优缺点详解

    PS:Nginx/LVS/HAProxy是目前使用最广泛的三种负载均衡软件,本人都在多个项目中实施过,参考了一些资料,结合自己的一些使用经验,总结一下. 一般对负载均衡的使用是随着网站规模的提升根据不 ...

  10. ORACLE表、索引和分区详解

    ORACLE表.索引和分区 一.数据库表 每种类型的表都有不同的特性,分别应用与不同的领域 堆组织表 聚簇表(共三种) 索引组织表 嵌套表 临时表 外部表和对象表 1.行迁移 建表过程中可以指定以下两 ...