C#.NET CORE的AddScoped之容器注入對象和接口實現的區別


一,代碼結構如下

 

 

二,我們線直接上代碼,如下:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using CoreIocTest.Models;
using CoreIocTest.Interface;

namespace CoreIocTest.Controllers
{
    public class HomeController : Controller
    {
        private TestOptions _testOptions;
        private IUser _user;

        public HomeController( TestOptions testOptions, IUser user)
        {
            _testOptions = testOptions;
            _user = user;
        }

        public IActionResult Index()
        {
            var isNull = _testOptions.test == null;

            if (isNull)
            {
                _testOptions.test = new Test();
            }
            if (!isNull)
            {
                _testOptions.IsChange = true;
            }

            var isNulluser = _user.test == null;

            if (isNulluser)
            {
                _user.test = new Test();
            }
            if (!isNulluser)
            {
                _user.IsChange = true;
            }

            return View();
        }
    }
}

startup

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CoreIocTest.Interface;
using CoreIocTest.Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace CoreIocTest
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            var op = new TestOptions() { Name = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ssffff") };
            services.AddScoped(s => op);
            services.AddScoped<IUser, User>();
            services.AddControllersWithViews();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

model

using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Text;

namespace CoreIocTest.Models
{
    public class TestOptions
    {
        public string Name { get; set; }
        /// <summary>
        /// 默認選取的實現命
        /// </summary>
        public bool IsChange { get; set; } = false;

        public Test test { get; set; }
    }

    public class Test { 
    public int Id { get; set; }
    }
}
using CoreIocTest.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace CoreIocTest.Interface
{
    public class User : IUser
    {
        public string Name { get; set; }
        /// <summary>
        /// 默認選取的實現命
        /// </summary>
        public bool IsChange { get; set; } = false;

        public Test test { get; set; }
    }
    public interface IUser
    {
        public string Name { get; set; }
        /// <summary>
        /// 默認選取的實現命
        /// </summary>
        public bool IsChange { get; set; }

        public Test test { get; set; }
    }
}

三,我們看下調試結果

頁面刷新第一次

 

 

 

 

 

刷新第二次

 

四 ,這個時候我們就奇怪了,為什么第二次請求isNull值改變了,不是說AddScoped是每次請求,容器的結果都是一個新實例么?

這個時候我們比較下isNull和isNulluser,isNull的IsChange值改變了,而isNulluser確是不變的,證明接口的實例每次都是一個新的實例,而直接將一個對象注入容器,每次構造注入拿出來的其實都是指向同一個地址的引用類型,實際上他們都是一個對象

 


免責聲明!

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



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