06-008 DependencyInjection 之 ServiceProvider
Posted on 2015-04-02 15:20 DotNet1010 阅读(162) 评论(0) 收藏 举报先看一下构造函数:
public ServiceProvider(IEnumerable<IServiceDescriptor> serviceDescriptors)
{
_root = this;
_table = new ServiceTable(serviceDescriptors);
_table.Add(typeof(IServiceProvider), new ServiceProviderService());
_table.Add(typeof(IServiceScopeFactory), new ServiceScopeService());
_table.Add(typeof(IEnumerable<>), new OpenIEnumerableService(_table));
/*
_genericServices[typeof(IEnumerable<>)]
= new List<IGenericService>() { new OpenIEnumerableService(_table) };
*/
}
初始就有三个类型;
看一下最核心的 GetService 方法:
private readonly ConcurrentDictionary<Type, Func<ServiceProvider, object>> _realizedServices
= new ConcurrentDictionary<Type, Func<ServiceProvider, object>>();
public object GetService(Type serviceType)
{
// 第一次调用时 Add
// 后面再次调用 Get
var realizedService = _table.RealizedServices.GetOrAdd(serviceType, key =>
{
var callSite = GetServiceCallSite(key, new HashSet<Type>());
if (callSite != null)
{
return RealizeService(_table, key, callSite);
// 这里返回 Func<ServiceProvider,object> 函数
}
return _ => null;
});
return realizedService.Invoke(this);
}
GetServiceCallSite 方法:
internal IServiceCallSite GetServiceCallSite(Type serviceType, ISet<Type> callSiteChain)
{
// ISet<Type> = new HashSet<Type>()
try
{
if (callSiteChain.Contains(serviceType))
{
throw new InvalidOperationException(Resources.FormatCircularDependencyException(serviceType));
}
callSiteChain.Add(serviceType);
ServiceEntry entry;
if (_table.TryGetEntry(serviceType, out entry))
{
return GetResolveCallSite(entry.Last, callSiteChain);
}
//Empty: Array.CreateInstance(itemType, 0);
object emptyIEnumerableOrNull = GetEmptyIEnumerableOrNull(serviceType);
if (emptyIEnumerableOrNull != null)
{
return new EmptyIEnumerableCallSite(serviceType, emptyIEnumerableOrNull);
}
return null;
}
finally
{
callSiteChain.Remove(serviceType);
}
}
GetResolveCallSite 方法的源代码:
internal IServiceCallSite GetResolveCallSite(IService service, ISet<Type> callSiteChain)
{
// 这里的 callSiteChain 有一个元素 serviceType
IServiceCallSite serviceCallSite = service.CreateCallSite(this, callSiteChain);
// 这里的IService ServiceEntry.Last
/*
1;internal class ClosedIEnumerableService : IService _table.Add(typeof(IEnumerable<>),
new OpenIEnumerableService(_table));
---CreateCallSite return new ClosedIEnumerableService.CallSite(_itemType, list.ToArray()); //对数组的包装
---CallSite.Invoke 创建数组 对数组赋值 然后返回.
2;internal class ServiceProviderService : IService, IServiceCallSite _table.Add(typeof(IServiceProvider), new ServiceProviderService());
---CreateCallSite return this;
---CallSite.Invoke return provider;
3;internal class ServiceScopeService : IService, IServiceCallSite _table.Add(typeof(IServiceScopeFactory), new ServiceScopeService());
---CreateCallSite return this;
---CallSite.Invoke return new ServiceScopeFactory(provider);
4;internal class FactoryService : IService, IServiceCallSite descriptor.ImplementationFactory != null
---CreateCallSite return this;
---CallSite.Invoke return _descriptor.ImplementationFactory(provider);
5;internal class InstanceService : IService, IServiceCallSite descriptor.ImplementationInstance != null
---CreateCallSite return this;
---CallSite.Invoke return _descriptor.ImplementationInstance;
6;internal class Service : IService descriptor.ImplementationType != null
---CreateCallSite
---6.1 构造函数有参数:
return new ConstructorCallSite(constructors[0], parameterCallSites);
--Invoke return _constructorInfo.Invoke(parameterValues);
---6.2 构造函数无参数:
return new CreateInstanceCallSite(_descriptor);
--Invoke return Activator.CreateInstance(_descriptor.ImplementationType);
----================================================================================
TransientCallSite ScopedCallSite SingletonCallSite
这三个类 两个作用 一个是与资源释放有关 另一个是与 LifeKind有关
*/
if (service.Lifecycle == LifecycleKind.Transient)
{
// 添加到 _disposables 中
return new TransientCallSite(serviceCallSite);
}
else if (service.Lifecycle == LifecycleKind.Scoped)
{
//添加到 _disposables 中
//添加到 _resolvedServices 同一Scope 只创建一次
return new ScopedCallSite(service, serviceCallSite);
}
else
{ //继承 ScopedCallSite
return new SingletonCallSite(service, serviceCallSite);
}
}
看一下 RealizeService 方法:
internal static Func<ServiceProvider, object> RealizeService(ServiceTable table, Type serviceType, IServiceCallSite callSite)
{
var callCount = 0;
return provider =>
{
if (Interlocked.Increment(ref callCount) == 2)
{
Task.Run(() =>
{
var providerExpression = Expression.Parameter(typeof(ServiceProvider), "provider");
var lambdaExpression = Expression.Lambda<Func<ServiceProvider, object>>(
callSite.Build(providerExpression),
providerExpression);
// 第二次调用的时候会替换 当第三次调用的时候才有可能会使用 具体看Task.Run 何时执行
// 为什么要这样做 暂不理解
table.RealizedServices[serviceType] = lambdaExpression.Compile(); //方法 Func<ServiceProvider,object>
/*
找到下面一段有关的文字:
@GrabYourPitchforks has suggested that it isn't necessary to use compiled expression trees to replace code
that does not use reflection.
If the performance impact is negligible, it might be better to use expression trees sparingly just for things
like constructor invocation to make the code simpler and easier to debug.
Once we have benchmarks, we can measure what the performance difference of compiling more or less.
This should help us decide which approach we should take.
---翻译如下:
@GrabYourPitchforks 曾建议在没有使用反射的情况下没有必要使用编译过的表达式树来替换代码。
如果性能影响是微不足道的,更好的方式是少使用表达式树,因为直接代码调用会使得代码更简单更易于调试。
一旦我们有了测试基准。我们能够测试使用编译的表达式树的多少与性能的关系,测试结果将帮助我们决定采用哪种方法。
*/
});
}
return callSite.Invoke(provider);
};
}
最后看一下 ScopedCallSite:
private readonly IService _key;
private readonly IServiceCallSite _serviceCallSite;
public ScopedCallSite(IService key, IServiceCallSite serviceCallSite)
{
// 为什么多一个 key ? 因为有可能已经创建过了 需要先查找判断
_key = key;
_serviceCallSite = serviceCallSite;
}
public virtual object Invoke(ServiceProvider provider)
{
object resolved;
lock (provider._sync) //private readonly object _sync = new object();
{
if (!provider._resolvedServices.TryGetValue(_key, out resolved))
{
//找不到 这里需要调用 同样要考虑到资源的释放
resolved = provider.CaptureDisposable(_serviceCallSite.Invoke(provider));
// 创建好后 还需要放到已经创建的列表中
provider._resolvedServices.Add(_key, resolved);
}
}
return resolved;
}
浙公网安备 33010602011771号