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 = 0; i < 3; 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 = 0; i < 3; 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("111111");
}
}
}