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确是不变的,证明接口的实例每次都是一个新的实例,而直接将一个对象注入容器,每次构造注入拿出来的其实都是指向同一个地址的引用类型,实际上他们都是一个对象

 

posted @ 2020-08-11 21:36  叶丶梓轩  阅读(4074)  评论(0编辑  收藏  举报