.net core系列之《.net core內置IOC容器ServiceCollection》


一、IOC介紹

  IOC:全名(Inversion of Control)-控制反轉

  IOC意味着我們將對象的創建控制權交給了外部容器,我們不管它是如何創建的,我們只需要知道,當我們想要某個實例時,我們可以直接從這個外部容器中去拿,而再也不需要我們去new了,充分體現了DIP(依賴倒置原則),也體現了我們經常掛在嘴邊的面向接口編程。

  DI:全名(Dependency Injection)-依賴注入

  DI意味着將類型之間的依賴關系注入到DI容器中

  在之前的.Net Framework中並沒有集成IOC,雖然Microsoft自己有一套"Unity",想要使用IOC+DI時,還需要我們自己去安裝包,進行三部曲等等各種操作

  比較流行的IOC容器技術:Autofac、Unity、NInject。。。

二、.net core內置IOC容器(ServiceCollection)

  1、打開NuGet包管理器,安裝 Microsoft.Extensions.DependencyInjection 包

  2、實現代碼如下:

    public interface ISqlHelper
    {
        void GetAll();
    }
    public class SqlServerHelper : ISqlHelper
    {
        public void GetAll()
        {
            Console.WriteLine("this is "+typeof(SqlServerHelper));
        }
    }
    static void Main(string[] args)
    {
        ServiceCollection services = new ServiceCollection();
        services.AddTransient<ISqlHelper, SqlServerHelper>();
        var provider=services.BuildServiceProvider();
        var sqlHelper=provider.GetService<ISqlHelper>();
        sqlHelper.GetAll();
        Console.ReadKey();
    }

  運行結果如下:

  

  當我們在執行業務邏輯時想要寫入一些日志(Log),必然會當然依賴這個類,那么會形成了SqlHelper類與Log類之前的依賴關系,我們可以將之前的依賴關系轉移到DI容器中,也就是依賴注入(DI),然后在DI容器獲取服務(對象)

  示例代碼如下:

    public interface ILog
    {
        void LogInfo(string msg);
    }
    public class Log : ILog
    {
        public void LogInfo(string msg)
        {
            Console.WriteLine(msg);
        }
    }
    static void Main(string[] args)
    {
        ServiceCollection services = new ServiceCollection();
        services.AddTransient<ILog, Log>();
        services.AddTransient<ISqlHelper, SqlServerHelper>();

        var provider=services.BuildServiceProvider();
        var sqlHelper= provider.GetService<ISqlHelper>();
        sqlHelper.GetAll();
        Console.ReadKey();
    }

  如果如下:

   

三、組件的生命周期

  1、Single:單例,全局唯一實例

  2、Scoped:作用域,在一個作用域中唯一實例,比如在Asp.Net Core應用程序中一次請求相當於一個Scoped

  3、Transient:瞬時,每次的實例都是一個新的對象

Transient:

        static void Main(string[] args)
        {
            ServiceCollection services = new ServiceCollection();
            services.AddTransient<ISqlHelper, SqlServerHelper>(); var provider=services.BuildServiceProvider();
            var sqlHelper=provider.GetService<ISqlHelper>();
            sqlHelper= provider.GetService<ISqlHelper>();

            Console.ReadKey();
        }

結果如下:

Single:

        static void Main(string[] args)
        {
            ServiceCollection services = new ServiceCollection();
            services.AddSingleton<ISqlHelper, SqlServerHelper>(); var provider=services.BuildServiceProvider();
            var sqlHelper=provider.GetService<ISqlHelper>();
            sqlHelper= provider.GetService<ISqlHelper>();

            Console.ReadKey();
        }

結果如下:

Scoped:

1、一個作用域下:

        static void Main(string[] args)
        {
            ServiceCollection services = new ServiceCollection();
            services.AddScoped<ISqlHelper, SqlServerHelper>(); var provider=services.BuildServiceProvider();
            var sqlHelper=provider.GetService<ISqlHelper>();
            sqlHelper= provider.GetService<ISqlHelper>();

            Console.ReadKey();
        }

結果如下:

 2、二個作用域下:

        static void Main(string[] args)
        {
            ServiceCollection services = new ServiceCollection();
            services.AddScoped<ISqlHelper, SqlServerHelper>();
            var provider=services.BuildServiceProvider();
            var scope1=provider.CreateScope();//在一個作用域下創建第一個子作用域
            var scope2= provider.CreateScope();//在一個作用域下創建第二個子作用域
            var sqlHelper= scope1.ServiceProvider.GetService<ISqlHelper>();
            sqlHelper= scope2.ServiceProvider.GetService<ISqlHelper>();

            Console.ReadKey();
        }

如果如下:

注意:由於是控制台項目,只能用子作用域來體現作用域的特點,在web項目中,一次請求就相當於一個作用域

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM