菜鸟的问题
好记性不如烂笔头~。~

1.参考资料:

 ①.http://www.jessetalk.cn/2017/11/06/di-in-aspnetcore/

 ②.https://www.cnblogs.com/GuZhenYin/p/8297145.html

 ③.https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-3.0

 ④.https://www.cnblogs.com/yilezhu/p/9998021.html

 ⑤.https://www.cnblogs.com/Erhao/p/11118642.html

2.依赖注入(DependencyInjection:DI):意思自身对象中的内置对象是通过注入的方式进行创建。形象的说,即由容器动态的将某个依赖关系注入到组件之中。

 ①.依赖?谁依赖谁?

    结果:当一个类需要另一个类协作来完成工作就产生了依赖。就如腾飞博客介绍的那样,对哒,就是酱紫(http://www.jessetalk.cn/2017/11/06/di-in-aspnetcore/)

 ②.注入?谁注入谁?

 结果:将所依赖的对象进行注入,包括所注入对象的所有资源(对象、资源、数据)???接口与实现??{好像还是不太对-.-.......};注入更能体现的是IOC思想

 ③.控制反转IOC(Inversion of Control)?

 结果:控制反转其实是一种思想,并非一种技术,就如DI一样,也只是一种设计思想,在不使用ioc设计下,我们创建对象一般都是使用new来创建一个对象;使用ioc后,创建对象的控制器有内部转到外部,接收外部传递进来的对象(依赖对象?),

 1.正转:就如鹏飞的文章中,AccountController自己来实例化需要的依

   2.反转?:为了在业务变化的时候尽量减少改动代码造成的问题(大多数文章都是酱紫理解的,感觉也很符合实际需求)

 ④.容器?core中自带的IOC容器(NET Core MVC中的Startup.cs)

 结果:用来管理依赖注入实例的坛子(感觉没毛病...);容器主要负责两件事:1.绑定服务于实例之间的关系(依赖?)2.获取实例,并对实例进行管理(创建与销毁)

 ⑤.实例生命周期?Transent/Scoped/Singleton(单例)

   1.Transent:每次请求时都会创建,并且永远不会被共享。

   2.Scoped:在同一个Scope内只初始化一个实例 ,可以理解为( 每一个request级别只创建一个实例,同一个http request会在一个 scope内)

   3.Singleton:整个应用程序生命周期内只会创建一个实例。该实例在需要它的所有组件之间共享。因此总是使用相同的实例。

 ⑥.使用DI的好处?

 结果:1.减少程序之间的松散耦合,减少依赖(?),有利于功能复用 2.使程序结构清晰,利于测试

 ⑦.常见的IOC框架:

   1.DependencyInjection(微软自带DI)

   2.Autofac

   3.Unity

 ⑧.注册服务的方式:

  ITestService.cs接口:

public interface ITestService
    {
        List<string> GetList(string a);
    }
View Code

  TestService.cs接口实现

public class TestService : ITestService
    {
        public List<string> GetList(string a)
        {
            return new List<string>() { "张三", "李四", "王五" };
        }
    }
View Code

  1.推荐的一种使用方式:

public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });


            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            // 注入服务
            services.AddTransient<ITestService, TestService>();
            services.AddDirectoryBrowser();  
        }

  2.另外的方式:

        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });


            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            // 注入服务
            //services.AddTransient<ITestService, TestService>();
            //services.AddDirectoryBrowser();

            //注入服务
            services.Add(new ServiceDescriptor(typeof(ITestService), typeof(TestService), ServiceLifetime.Transient));
            
        }

  3.Action注入的方法:使用[FromServices]

 public class HomeController : Controller
    {
 
private readonly ITestService _testService;
//此处为构造函数注入方式
public HomeController(ITestService testService) { _testService = testService; } //这里采用推荐的依赖注入方式 public IActionResult Index() { ViewBag.date = _testService.GetList(""); return View(); } //这里采用Action注入的方式 public IActionResult Privacy([FromServices] ITestService testService1) { ViewBag.date = testService1.GetList(""); return View(); }

3.Example

 ①.实例生命周期实例:

 -(1).新建一个ASP.NET Core Web应用程序.

 -(2).新建三个接口,三个接口实现类

ITestServiceTransient.cs

   /// <summary>
    /// Transient:瞬时的
    /// </summary>
    public interface ITestServiceTransient
    {
        Guid TrGudi { get; }
        List<string> GetList(string a);

    }
View Code

ITestServiceScoped.cs

    /// <summary>
    /// Scoped:作用域的
    /// </summary>
    public interface ITestServiceScoped
    {
        Guid ScoGuid { get; }
        List<string> GetList();
    }
View Code

ITestServiceSingleton.cs

   /// <summary>
    /// Singleton:唯一的
    /// </summary>
    public interface ITestServiceSingleton
    {
        Guid SingGuid { get; }
        List<string> GetList();
    }
View Code

TestServiceTransient.cs

    public class TestServiceTransient : ITestServiceTransient
    {
        public TestServiceTransient()
        {
            TrGudi = Guid.NewGuid();
        }
        public Guid TrGudi { get; set; }


        public List<string> GetList(string a)
        {
            return new List<string>() { "AA", "BB", "CC" };
        }
    }
View Code

TestServiceScoped.cs

   public class TestServiceScoped : ITestServiceScoped
    {
        public TestServiceScoped()
        {
            ScoGuid = Guid.NewGuid();
        }
        public Guid ScoGuid { get; set; }

        public List<string> GetList()
        {
            return new List<string>() { "A", "B", "C" };
        }
    }
View Code

TestServiceSingleton.cs

    public class TestServiceSingleton : ITestServiceSingleton
    {
        public TestServiceSingleton()
        {
            SingGuid = Guid.NewGuid();
        }
        public Guid SingGuid { get; set; }

        public List<string> GetList()
        {
            return new List<string>() { "a", "b", "c" };
        }
    }
View Code

 -(3).注入服务:Startup.cs

public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });


            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            // 注入服务
            services.AddTransient<ITestServiceTransient, TestServiceTransient>();
            services.AddSingleton<ITestServiceSingleton, TestServiceSingleton>();
            services.AddScoped<ITestServiceScoped, TestServiceScoped>();
            services.AddDirectoryBrowser();

            
        }
View Code

 -(4).修改Home下的控制器跟视图

HomeControlle.cs

public class HomeController : Controller
    {
        
        private readonly ITestServiceTransient _testServiceTransient;
        private readonly ITestServiceSingleton _testServiceSingleton;
        private readonly ITestServiceScoped _testServiceScoped;

        // 构造函数注入
        public HomeController(ITestServiceTransient testServiceTransient, ITestServiceSingleton testServiceSingleton, ITestServiceScoped testServiceScoped)
        {
            _testServiceTransient = testServiceTransient;
            _testServiceSingleton = testServiceSingleton;
            _testServiceScoped = testServiceScoped;
        }
        //这里采用推荐的注入方式
        public IActionResult Index()
        {
            ViewBag.date = _testServiceTransient.GetList("");
            ViewBag.guidTr = _testServiceTransient.TrGudi;
            ViewBag.guidSco = _testServiceScoped.ScoGuid;
            ViewBag.guidSing = _testServiceSingleton.SingGuid;
            
            return View();
        }

        //这里采用Action注入的方式
        public IActionResult Privacy([FromServices] ITestServiceTransient testServiceTransient,[FromServices] ITestServiceScoped testServiceScoped,[FromServices] ITestServiceSingleton testServiceSingleton )
        {
            ViewBag.date = testServiceTransient.GetList("");
            ViewBag.guidTr = testServiceTransient.TrGudi;
            ViewBag.guidTr1 = _testServiceTransient.TrGudi;// ?? 这个对象是来至于构造函数的??
            ViewBag.guidSco = testServiceScoped.ScoGuid;
            ViewBag.guidSco1 = _testServiceScoped.ScoGuid;
            ViewBag.guidSing = testServiceSingleton.SingGuid;
            ViewBag.guidSing1 = _testServiceSingleton.SingGuid;
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
    }
View Code

Index.cshtml

@{
    ViewData["Title"] = "Home Page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
    @foreach (var item in ViewBag.date)
    {
        <h5>@item</h5>
    }
</div>
<h2>瞬时的:@ViewBag.guidTr</h2>
<h2>瞬时的:@ViewBag.guidTr</h2>
<h2>作用域的:@ViewBag.guidSco</h2>
<h2>作用域的:@ViewBag.guidSco</h2>
<h2>唯一的:@ViewBag.guidSing</h2>
<h2>唯一的:@ViewBag.guidSing</h2>
View Code

Privacy.cshtml

@{
    ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>

<p>Use this page to detail your site's privacy policy.</p>
@foreach (var item in ViewBag.date)
{
    <h5>@item</h5>
}
<h2>瞬时的:@ViewBag.guidTr</h2>
<h2>瞬时的:@ViewBag.guidTr1</h2>
<h2>作用域的:@ViewBag.guidSco</h2>
<h2>作用域的:@ViewBag.guidSco1</h2>
<h2>唯一的:@ViewBag.guidSing</h2>
<h2>唯一的:@ViewBag.guidSing1</h2>
View Code

 -(5).输出:来回点击Home与Privacy进行切换访问,观察3个属性周期的变化

  Home:

  Privacy:

 -(6).多次点击Home或者Privacy页面进行访问,发现以下结论:

 --1.Home与Privacy页面的唯一属性Singleton是一样,说明在同一个程序的生命周期内,Singleton值是唯一的(全局只创建一次,第一次被请求的时候被创建,然后就一直使用这一个

 --2.Home与Privacy页面的作用域值Scoped是随着改变的,并且两个视图页面的值不一样,说明两个视图作为两个单独的对象来进行访问( 在同作用域,服务每个请求只创建一次

 --3.Home的瞬时值Transient在每次访问都会重新进行创建(这个生命周期最适合轻量级,无状态的服务),Privacy中的两个Transient值每次访问都不相同(?),是否是因为Privacy视图中的“ViewBag.guidTr1 = _testServiceTransient.TrGudi;”来至于构造函数?(每次请求时都会创建的瞬时生命周期服务

 

posted on 2019-10-08 17:45  ArSang-Blog  阅读(279)  评论(0编辑  收藏  举报