导航

06-004 DependencyInjection 之 IServiceCallSite(1)

Posted on 2015-03-25 10:22  DotNet1010  阅读(131)  评论(0)    收藏  举报

看一下 IServiceCallSite 接口的代码:

 internal interface IServiceCallSite
    {
        object Invoke(ServiceProvider provider); //返回具体的对象

        Expression Build(Expression provider);  //返回对应的 Expression
    }

ClosedIEnumerableService 类中有一个内部类:

private class CallSite : IServiceCallSite{}

Service 类中有几个内部类:

 private class ConstantCallSite : IServiceCallSite{}         //01
 private class ConstructorCallSite : IServiceCallSite{}      //02
 private class CreateInstanceCallSite : IServiceCallSite{}   //03

ServicePrivider 中有几个内部类:

private class EmptyIEnumerableCallSite : IServiceCallSite{}
private class TransientCallSite : IServiceCallSite{}
private class ScopedCallSite : IServiceCallSite{}
private class SingletonCallSite : ScopedCallSite{}

还有如下几个类也实现了  IServiceCallSite:

 internal class FactoryService : IService, IServiceCallSite{}
 internal class InstanceService : IService, IServiceCallSite{}
 internal class ServiceProviderService : IService, IServiceCallSite{}
 internal class ServiceScopeService : IService, IServiceCallSite{}

看一下 ConstantCallSite 的代码:

       private class ConstantCallSite : IServiceCallSite
        {
            private readonly object _defaultValue;

            public ConstantCallSite(object defaultValue)
            {
                _defaultValue = defaultValue;
            }

            public object Invoke(ServiceProvider provider)
            {
				//返回创建时传入的值 和provider 没关系
                return _defaultValue;
            }

            public Expression Build(Expression provider)
            {
				// 返回具体值的表达式
                return Expression.Constant(_defaultValue);
            }
        }

 调用的相关代码:

IServiceCallSite[] parameterCallSites = new IServiceCallSite[parameters.Length];
 if (parameterCallSites[index] == null && parameters[index].HasDefaultValue)
  {
       parameterCallSites[index] = new ConstantCallSite(parameters[index].DefaultValue);
  }

 继续看一下 ConstructorCallSite:

private class ConstructorCallSite : IServiceCallSite
        {
            private readonly ConstructorInfo _constructorInfo;
            private readonly IServiceCallSite[] _parameterCallSites; //构造函数可能有多个参数

            public ConstructorCallSite(ConstructorInfo constructorInfo, IServiceCallSite[] parameterCallSites)
            {
                _constructorInfo = constructorInfo;
                _parameterCallSites = parameterCallSites;
            }

            public object Invoke(ServiceProvider provider)
            {
                object[] parameterValues = new object[_parameterCallSites.Length];
                for (var index = 0; index != parameterValues.Length; ++index)
                {
					// 如果是 ConstantCallSite 则 parameterValues[index] 则等于具体的值;
					parameterValues[index] = _parameterCallSites[index].Invoke(provider);
                }

                try
                {
					// 返回创建的对象 这里相当于New() 创建的对象
					return _constructorInfo.Invoke(parameterValues);
                }
                catch (Exception ex)
                {
                    ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                    // The above line will always throw, but the compiler requires we throw explicitly.
                    throw;
                }
            }

            public Expression Build(Expression provider)
            {
                var parameters = _constructorInfo.GetParameters();
                return Expression.New(
                    _constructorInfo,
                    _parameterCallSites.Select((callSite, index) =>
                        Expression.Convert(             //这里做一下类型转换
				callSite.Build(provider),  //如果是 ConstantCallSite 则返回: Expression.Constant(_defaultValue)
				parameters[index].ParameterType)));
            }
        }

 继续看一下CreateInstanceCallSite:

	/// <summary>
		/// 简单对象 构造函数无参数对象的创建
		/// </summary>
        private class CreateInstanceCallSite : IServiceCallSite
        {
            private readonly IServiceDescriptor _descriptor;

            public CreateInstanceCallSite(IServiceDescriptor descriptor)
            {
                _descriptor = descriptor;
            }

            public object Invoke(ServiceProvider provider)
            {
                try
                {           //使用指定对象的默认构造器来创建对象实例
                    return Activator.CreateInstance(_descriptor.ImplementationType);
                }
                catch (Exception ex)
                {
                    ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                    // The above line will always throw, but the compiler requires we throw explicitly.
                    throw;
                }
            }

            public Expression Build(Expression provider)
            {
				// 与 ConstructorCallSite 比 没有参数
				return Expression.New(_descriptor.ImplementationType);
            }
        }

 调用的相关代码:

      public IServiceCallSite CreateCallSite(ServiceProvider provider, ISet<Type> callSiteChain)
        {
            ConstructorInfo[] constructors = _descriptor.ImplementationType.GetTypeInfo()
                .DeclaredConstructors
                .Where(IsInjectable) //return constructor.IsPublic && constructor.GetParameters().Length != 0;
                .ToArray();

            // TODO: actual service-fulfillment constructor selection
            if (constructors.Length == 1)
            {
                ParameterInfo[] parameters = constructors[0].GetParameters();
                IServiceCallSite[] parameterCallSites = new IServiceCallSite[parameters.Length];
                //此处省略部分代码............
                return new ConstructorCallSite(constructors[0], parameterCallSites);
            }

            return new CreateInstanceCallSite(_descriptor);
        }

 关于ClosedIEnumerableService 中的 private class CallSite : IServiceCallSite{}

 Invoke 方法 实现了  创建指定类型 长度的数组,并对数组进行赋值;然后返回数据的功能。这列不在列代码了。