码迷,mamicode.com
首页 > 其他好文 > 详细

微软的实现4

时间:2015-05-24 21:50:53      阅读:139      评论:0      收藏:0      [点我收藏+]

标签:

微软的实现(4)

[Asp.net 5] DependencyInjection项目代码分析

[Asp.net 5] DependencyInjection项目代码分析2-Autofac

[Asp.net 5] DependencyInjection项目代码分析3-Ninject

[Asp.net 5] DependencyInjection项目代码分析4-微软的实现(1)

[Asp.net 5] DependencyInjection项目代码分析4-微软的实现(2)

[Asp.net 5] DependencyInjection项目代码分析4-微软的实现(3)

 

如果想对本篇有个更好的了解,建议需要先看

[Asp.net 5] DependencyInjection项目代码分析

[Asp.net 5] DependencyInjection项目代码分析4-微软的实现(1)

[Asp.net 5] DependencyInjection项目代码分析4-微软的实现(2)”。

"[Asp.net 5] DependencyInjection项目代码分析4-微软的实现(3)"

继续ServiceProvider类

在之前的讲解中我们提到过Service类调用CreateCallSite方法时会递归调用,但是我们没具体说明如何递归调的。实际上Service类,通过反射创建实例的时候,会实例化的参数对象,而实例话参数对象通过ServiceProvider类创建,而ServiceProvider类创建参数的实例,又需要通过Service类(如果是通过Type注册的)创建。下面我们把Service的CreateInstanceCallSite方法以及ServiceProvider相关的方法列出来。

技术分享 Service的CreateCallSite
技术分享 ServiceProvider

对于Service的CreateCallSite方法,之前我们已经介绍过,现在我们重点讲下ServiceProvider的GetServiceCallSite方法。从上面代码中我们发现参数中含有“ ISet<Type> callSiteChain”,这个参数是防止发生A的构造函数有B类型参数,B的构织函数中有A类型参数,当A,B都是通过类型注入的,那么系统会陷入死循环。而callSiteChain得作用就是防止这样的死循环发生,当创建A时,会在callSiteChain中查询历史中是否有A的创建过程,如果有则说明发生死循环了,直接抛出异常,结束;如果没有将A加入到callSiteChain中,继续创建其参数。GetResolveCallSite方法比较简单,对于ServiceProvider已经能够获取的IServiceCallSite实例,进行包装,已保证生成的实例能够适应不同的Scoped(该处应该使用设计模式中的代理模式,不过我设计模式不过关,请帮忙确认)。

对于TransientCallSite、ScopedCallSite、SingletonCallSite以及EmptyIEnumerableCallSite代码,如下所示:

技术分享 View Code

 该工程所有类的关系图(包括内部类以及一些接口),如下所示:

技术分享

补充说明

  • IServiceCallSite中定义了Build方法,该方法使用了Expression,但是该篇文章没有对其进行具体的研究,并且Build方法是相对独立的。
  • 对于OpenIEnumerableService泛型省略详解。

示例测试代码:

技术分享
    public static class TestServices
    {
        public static IServiceCollection DefaultServices()
        {
            var services = new ServiceCollection();

            services.AddTransient<IFakeService, FakeService>();
            services.AddTransient<IFakeMultipleService, FakeOneMultipleService>();
            services.AddTransient<IFakeMultipleService, FakeTwoMultipleService>();
            services.AddTransient<IFakeOuterService, FakeOuterService>();
            services.AddInstance<IFakeServiceInstance>(new FakeService() { Message = "Instance" });
            services.AddScoped<IFakeScopedService, FakeService>();
            services.AddSingleton<IFakeSingletonService, FakeService>();
            services.AddTransient<IDependOnNonexistentService, DependOnNonexistentService>();
            services.AddTransient<IFakeOpenGenericService<string>, FakeService>();
            services.AddTransient(typeof(IFakeOpenGenericService<>), typeof(FakeOpenGenericService<>));

            services.AddTransient<IFactoryService>(provider =>
            {
                var fakeService = provider.GetService<IFakeService>();
                return new TransientFactoryService
                {
                    FakeService = fakeService,
                    Value = 42
                };
            });

            services.AddScoped(provider =>
            {
                var fakeService = provider.GetService<IFakeService>();
                return new ScopedFactoryService
                {
                    FakeService = fakeService,
                };
            });

            services.AddTransient<ServiceAcceptingFactoryService, ServiceAcceptingFactoryService>();
            return services;
        }
    }


public class ServiceProviderContainerTests : ScopingContainerTestBase
    {
        protected override IServiceProvider CreateContainer()
        {
            return TestServices.DefaultServices().BuildServiceProvider();
        }

[Fact]
        public void ScopedServiceCanBeResolved()
        {
            IServiceProvider container = CreateContainer();

            var scopeFactory = container.GetService<IServiceScopeFactory>();
            using (var scope = scopeFactory.CreateScope())
            {
                var containerScopedService = container.GetService<IFakeScopedService>();
                var scopedService1 = scope.ServiceProvider.GetService<IFakeScopedService>();
                Thread.Sleep(200);
                var scopedService2 = scope.ServiceProvider.GetService<IFakeScopedService>();

                Assert.NotEqual(containerScopedService, scopedService1);
                Assert.Equal(scopedService1, scopedService2);
            }
        }
}
技术分享

 

 
 

微软的实现4

标签:

原文地址:http://www.cnblogs.com/Leo_wl/p/4526406.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!