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"); } } }