开源项目 08 IOC Autofac

 

 

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

}

 

posted @ 2019-07-16 15:20  古兴越  阅读(263)  评论(0编辑  收藏  举报