导航

06-005 DependencyInjection 之 ServiceEntry

Posted on 2015-03-25 15:17  DotNet1010  阅读(152)  评论(0)    收藏  举报

先上代码:

 internal class ServiceEntry
    {
        private object _sync = new object();

        public ServiceEntry(IService service)
        {
            First = service;
            Last = service;
        }

        public IService First { get; private set; }
        public IService Last { get; private set; }

        public void Add(IService service)
        {
            lock (_sync)
            {
                Last.Next = service;
                Last = service;
            }
        }
    }

 先说说这个类是做什么用的?

非泛型的ServiceType 会被存储到如下的列表中:

 private readonly Dictionary<Type, ServiceEntry> _services;

 添加到集合的代码如下:

  public void Add(Type serviceType, IService service)
        {
            lock (_sync)
            {
                ServiceEntry entry;
                if (_services.TryGetValue(serviceType, out entry))
                {
			 //取出 ServiceEntry 调用 entry.Add
		         entry.Add(service);
                }
                else
                {
		   //这里是第一次添加 用ServiceEntry 包装一下 service
                    _services[serviceType] = new ServiceEntry(service);
                }
            }
        }

 假定有接口 IA (非泛型接口)  实现类有 A1;A2;A3;

首先都添加到ServiceCollection 里面; 扩展方法本质上都是在调用  new ServiceDescriptor 对象;

services.Add(new ServiceDescriptor(typeof(IA), typeof(A1), LifecycleKind.Transient));
services.Add(new ServiceDescriptor(typeof(IA), typeof(A2), LifecycleKind.Transient));
services.Add(new ServiceDescriptor(typeof(IA), typeof(A2), LifecycleKind.Transient));

 他们被存储在这里:

 private readonly List<IServiceDescriptor> _descriptors = new List<IServiceDescriptor>();

 当调用 services.BuildServiceProvider() 方法时;依次调用了:

new ServiceProvider 里调用了 new ServiceTable

new ServiceProvider(IEnumerable<IServiceDescriptor> services);
new ServiceTable(   IEnumerable<IServiceDescriptor> services);

 ServiceTable 构造函数里 遍历  IEnumerable<IServiceDescriptor> services   也就是我们存储IA A1的list:List<IServiceDescriptor>

 调用Add 方法:public void Add(Type serviceType, IService service)

这里:有如下关系:internal class InstanceService : IService, IServiceCallSite{}

private readonly Dictionary<Type, ServiceEntry> _services;
_services = new Dictionary<Type, ServiceEntry>();
_services.Add(descriptor.ServiceType, new InstanceService(descriptor));

 Add 方法的内部:

//这里是第一次添加 用ServiceEntry 包装一下 service
_services[serviceType] = new ServiceEntry(service);
//相当于下列代码:
_services[typeof(IA)] = new ServiceEntry(new InstanceService(new ServiceDescriptor(typeof(IA), typeof(A1), LifecycleKind.Transient)));

 这时候 ServiceEntry

即:_services[typeof(IA)].First=_services[typeof(IA)].Last=new InstanceService(new ServiceDescriptor(typeof(IA), typeof(A1), LifecycleKind.Transient)));

我们简写为:S(IA).First=S(IA).Last=A1服务类;

Add A2后呢?

S(IA).First=A1服务类;
A1服务类.Next=A2服务类;
S(IA).Last=A2服务类;

 Add A3后呢?

S(IA).First=A1服务类;
A1服务类.Next=A2服务类;
A2服务类.Next=A3服务类;
S(IA).Last=A3服务类;

 这里面没有替换 所有的 A1 A2 A3 都被保存了下来,按照顺序连接在一起。

那么真正调用的时候用的是哪个呢?

答案是 S(IA).Last;即 A3服务类;符合最后添加使用原则。

此节结束。