public object Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope) { return(VisitCallSite(callSite, new RuntimeResolverContext { Scope = scope })); }
protected override object VisitRootCache(ServiceCallSite callSite, RuntimeResolverContext context) { if (callSite.Value is object value) { // Value already calculated, return it directly return(value); } var lockType = RuntimeResolverLock.Root; ServiceProviderEngineScope serviceProviderEngine = context.Scope.Engine.Root; lock (callSite) { // Lock the callsite and check if another thread already cached the value if (callSite.Value is object resolved) { return(resolved); } resolved = VisitCallSiteMain(callSite, new RuntimeResolverContext { Scope = serviceProviderEngine, AcquiredLocks = context.AcquiredLocks | lockType }); serviceProviderEngine.CaptureDisposable(resolved); callSite.Value = resolved; return(resolved); } }
internal object GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope) { var realizedService = RealizedServices.GetOrAdd(serviceType, _createServiceAccessor); _callback?.OnResolve(serviceType, serviceProviderEngineScope); return(realizedService.Invoke(serviceProviderEngineScope)); }
public ExpressionResolverBuilder(CallSiteRuntimeResolver runtimeResolver, IServiceScopeFactory serviceScopeFactory, ServiceProviderEngineScope rootScope) : base() { _runtimeResolver = runtimeResolver ?? throw new ArgumentNullException(nameof(runtimeResolver)); _serviceScopeFactory = serviceScopeFactory; _rootScope = rootScope; }
public void DoubleDisposeWorks() { var engine = new FakeEngine(); var serviceProviderEngineScope = new ServiceProviderEngineScope(engine); serviceProviderEngineScope.ResolvedServices.Add(new ServiceCacheKey(typeof(IFakeService), 0), null); serviceProviderEngineScope.Dispose(); serviceProviderEngineScope.Dispose(); }
public void Dispose_DoesntClearResolvedServices() { var serviceProviderEngineScope = new ServiceProviderEngineScope(null); serviceProviderEngineScope.ResolvedServices.Add(new ServiceCacheKey(typeof(IFakeService), 0), null); serviceProviderEngineScope.Dispose(); Assert.Single(serviceProviderEngineScope.ResolvedServices); }
public void DoubleDisposeWorks() { var provider = new ServiceProvider(new ServiceCollection(), ServiceProviderOptions.Default); var serviceProviderEngineScope = new ServiceProviderEngineScope(provider, isRootScope: true); serviceProviderEngineScope.ResolvedServices.Add(new ServiceCacheKey(typeof(IFakeService), 0), null); serviceProviderEngineScope.Dispose(); serviceProviderEngineScope.Dispose(); }
protected ServiceProviderEngine(IEnumerable <ServiceDescriptor> serviceDescriptors) { _createServiceAccessor = CreateServiceAccessor; Root = new ServiceProviderEngineScope(this, isRoot: true); RuntimeResolver = new CallSiteRuntimeResolver(); CallSiteFactory = new CallSiteFactory(serviceDescriptors); CallSiteFactory.Add(typeof(IServiceProvider), new ServiceProviderCallSite()); CallSiteFactory.Add(typeof(IServiceScopeFactory), new ServiceScopeFactoryCallSite()); RealizedServices = new ConcurrentDictionary <Type, Func <ServiceProviderEngineScope, object> >(); }
public ILEmitResolverBuilder(CallSiteRuntimeResolver runtimeResolver, IServiceScopeFactory serviceScopeFactory, ServiceProviderEngineScope rootScope) { if (runtimeResolver == null) { throw new ArgumentNullException(nameof(runtimeResolver)); } _runtimeResolver = runtimeResolver; _serviceScopeFactory = serviceScopeFactory; _rootScope = rootScope; }
public void ResolvedServicesAfterDispose_ThrowsObjectDispose() { var engine = new FakeEngine(); var serviceProviderEngineScope = new ServiceProviderEngineScope(engine); serviceProviderEngineScope.ResolvedServices.Add(new ServiceCacheKey(typeof(IFakeService), 0), null); serviceProviderEngineScope.Dispose(); Assert.Throws <ObjectDisposedException>(() => serviceProviderEngineScope.ResolvedServices); }
protected ServiceProviderEngine(IEnumerable <ServiceDescriptor> serviceDescriptors, IServiceProviderEngineCallback callback) { _createServiceAccessor = CreateServiceAccessor; _callback = callback; Root = new ServiceProviderEngineScope(this); //实例化根容器 RuntimeResolver = new CallSiteRuntimeResolver(); //实例化 CallSite对象访问者对象 CallSiteFactory = new CallSiteFactory(serviceDescriptors); CallSiteFactory.Add(typeof(IServiceProvider), new ServiceProviderCallSite()); CallSiteFactory.Add(typeof(IServiceScopeFactory), new ServiceScopeFactoryCallSite()); // 缓存一个ServiceScopeFactoryCallSite服务,相当于缓存一个ServiceProviderEngine,根据此对象进行创建子容器 RealizedServices = new ConcurrentDictionary <Type, Func <ServiceProviderEngineScope, object> >(); //缓存实例化对象的工厂 }
/// <summary> /// 这个方法获取服务实例对象,可以看到具有两个此方法,并且第一个调用了第二个,并将顶级容器Root进行了传入,而在第二个方法中,获取并添加_createServiceAccessor委托,然后调用此委托进行获取服务实例 /// </summary> /// <param name="serviceType"></param> /// <param name="serviceProviderEngineScope"></param> /// <returns></returns> internal object GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope) { if (_disposed) { ThrowHelper.ThrowObjectDisposedException(); } var realizedService = RealizedServices.GetOrAdd(serviceType, _createServiceAccessor); //添加并获取根据容器对象实例化对象的方法,其方法由子类进行重写 _callback?.OnResolve(serviceType, serviceProviderEngineScope); // 验证是否允许进行实例化对象 return(realizedService.Invoke(serviceProviderEngineScope)); }
protected ServiceProviderEngine(IEnumerable <ServiceDescriptor> serviceDescriptors, IServiceProviderEngineCallback callback) { _createServiceAccessor = CreateServiceAccessor; _callback = callback; Root = new ServiceProviderEngineScope(this); RuntimeResolver = new CallSiteRuntimeResolver(); ExpressionBuilder = new CallSiteExpressionBuilder(RuntimeResolver, this, Root); CallSiteFactory = new CallSiteFactory(serviceDescriptors); CallSiteFactory.Add(typeof(IServiceProvider), new ServiceProviderCallSite()); CallSiteFactory.Add(typeof(IServiceScopeFactory), new ServiceScopeFactoryCallSite()); }
internal object GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope) { if (_disposed) { ThrowHelper.ThrowObjectDisposedException(); } var realizedService = RealizedServices.GetOrAdd(serviceType, _createServiceAccessor); _callback?.OnResolve(serviceType, serviceProviderEngineScope); return(realizedService.Invoke(serviceProviderEngineScope)); }
internal object GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope) { if (_disposed) { ThrowHelper.ThrowObjectDisposedException(); } Func <ServiceProviderEngineScope, object> realizedService = RealizedServices.GetOrAdd(serviceType, _createServiceAccessor); _callback?.OnResolve(serviceType, serviceProviderEngineScope); DependencyInjectionEventSource.Log.ServiceResolved(serviceType); return(realizedService.Invoke(serviceProviderEngineScope)); }
public ExpressionResolverBuilder(CallSiteRuntimeResolver runtimeResolver, IServiceScopeFactory serviceScopeFactory, ServiceProviderEngineScope rootScope) { if (runtimeResolver == null) { throw new ArgumentNullException(nameof(runtimeResolver)); } _scopeResolverCache = new ConcurrentDictionary <ServiceCacheKey, Func <ServiceProviderEngineScope, object> >(); _runtimeResolver = runtimeResolver; _serviceScopeFactory = serviceScopeFactory; _rootScope = rootScope; _buildTypeDelegate = (key, cs) => BuildNoCache(cs); }
public ILEmitResolverBuilder(CallSiteRuntimeResolver runtimeResolver, IServiceScopeFactory serviceScopeFactory, ServiceProviderEngineScope rootScope) : base() { if (runtimeResolver == null) { throw new ArgumentNullException(nameof(runtimeResolver)); } _runtimeResolver = runtimeResolver; _serviceScopeFactory = serviceScopeFactory; _rootScope = rootScope; _scopeResolverCache = new ConcurrentDictionary <ServiceCacheKey, GeneratedMethod>(); _buildTypeDelegate = (key, cs) => BuildTypeNoCache(cs); }
internal object GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope) //获取服务类型对应的服务实例,首先会从 RealizedServices 中获取服务类型对应的创建实例方法 (如果没有就会在运行是将该方法加入 RealizedServices,运行时动态添加)。 //获取的创建实例的委托方法需要一个类型为 ServiceProviderEngineScope 的参数才能调用,返回服务实例。 //最后调用这个创建服务类型实例的方法。 { if (_disposed) { ThrowHelper.ThrowObjectDisposedException(); } var realizedService = RealizedServices.GetOrAdd(serviceType, _createServiceAccessor); _callback?.OnResolve(serviceType, serviceProviderEngineScope); return(realizedService.Invoke(serviceProviderEngineScope)); }
protected ServiceProviderEngine( IEnumerable <ServiceDescriptor> serviceDescriptors, IServiceProviderEngineCallback callback, IInterceptingProxyFactory interceptingProxyFactory) { _createServiceAccessor = CreateServiceAccessor; _callback = callback; Root = new ServiceProviderEngineScope(this); RuntimeResolver = new CallSiteRuntimeResolver(); CallSiteFactory = new CallSiteFactory(serviceDescriptors, interceptingProxyFactory); CallSiteFactory.Add(typeof(IServiceProvider), new ServiceProviderCallSite()); CallSiteFactory.Add(typeof(IServiceScopeFactory), new ServiceScopeFactoryCallSite()); RealizedServices = new ConcurrentDictionary <Type, Func <ServiceProviderEngineScope, object> >(); }
private object VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType) { bool lockTaken = false; Dictionary <ServiceCacheKey, object> resolvedServices = serviceProviderEngine.ResolvedServices; // Taking locks only once allows us to fork resolution process // on another thread without causing the deadlock because we // always know that we are going to wait the other thread to finish before // releasing the lock if ((context.AcquiredLocks & lockType) == 0) { Monitor.Enter(resolvedServices, ref lockTaken); } try { return(ResolveService(callSite, context, lockType, serviceProviderEngine)); } finally { if (lockTaken) { Monitor.Exit(resolvedServices); } } }
private object VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType) { bool lockTaken = false; object sync = serviceProviderEngine.Sync; Dictionary <ServiceCacheKey, object> resolvedServices = serviceProviderEngine.ResolvedServices; // Taking locks only once allows us to fork resolution process // on another thread without causing the deadlock because we // always know that we are going to wait the other thread to finish before // releasing the lock if ((context.AcquiredLocks & lockType) == 0) { Monitor.Enter(sync, ref lockTaken); } try { // Note: This method has already taken lock by the caller for resolution and access synchronization. // For scoped: takes a dictionary as both a resolution lock and a dictionary access lock. if (resolvedServices.TryGetValue(callSite.Cache.Key, out object resolved)) { return(resolved); } resolved = VisitCallSiteMain(callSite, new RuntimeResolverContext { Scope = serviceProviderEngine, AcquiredLocks = context.AcquiredLocks | lockType }); serviceProviderEngine.CaptureDisposable(resolved); resolvedServices.Add(callSite.Cache.Key, resolved); return(resolved); } finally { if (lockTaken) { Monitor.Exit(sync); } } }
private object ResolveService(ServiceCallSite callSite, RuntimeResolverContext context, RuntimeResolverLock lockType, ServiceProviderEngineScope serviceProviderEngine) { Dictionary <ServiceCacheKey, object> resolvedServices = serviceProviderEngine.ResolvedServices; if (!resolvedServices.TryGetValue(callSite.Cache.Key, out object resolved)) { resolved = VisitCallSiteMain(callSite, new RuntimeResolverContext { Scope = serviceProviderEngine, AcquiredLocks = context.AcquiredLocks | lockType }); serviceProviderEngine.CaptureDisposable(resolved); resolvedServices.Add(callSite.Cache.Key, resolved); } return(resolved); }
private object VisitCache(ServiceCallSite scopedCallSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType) { bool lockTaken = false; var resolvedServices = serviceProviderEngine.ResolvedServices; // Taking locks only once allows us to fork resolution process // on another thread without causing the deadlock because we // always know that we are going to wait the other thread to finish before // releasing the lock if ((context.AcquiredLocks & lockType) == 0) { Monitor.Enter(resolvedServices, ref lockTaken); } try { if (!resolvedServices.TryGetValue(scopedCallSite.Cache.Key, out var resolved)) { resolved = VisitCallSiteMain(scopedCallSite, new RuntimeResolverContext { Scope = serviceProviderEngine, AcquiredLocks = context.AcquiredLocks | lockType }); serviceProviderEngine.CaptureDisposable(resolved); resolvedServices.Add(scopedCallSite.Cache.Key, resolved); } return(resolved); } finally { if (lockTaken) { Monitor.Exit(resolvedServices); } } }
public ILEmitResolverBuilder(ServiceProvider serviceProvider) { _rootScope = serviceProvider.Root; _scopeResolverCache = new ConcurrentDictionary <ServiceCacheKey, GeneratedMethod>(); _buildTypeDelegate = (key, cs) => BuildTypeNoCache(cs); }
public ExpressionResolverBuilder(ServiceProvider serviceProvider) { _rootScope = serviceProvider.Root; _scopeResolverCache = new ConcurrentDictionary <ServiceCacheKey, Func <ServiceProviderEngineScope, object> >(); _buildTypeDelegate = (key, cs) => BuildNoCache(cs); }
private object ResolveService(ServiceCallSite callSite, RuntimeResolverContext context, RuntimeResolverLock lockType, ServiceProviderEngineScope serviceProviderEngine) { IDictionary <ServiceCacheKey, object> resolvedServices = serviceProviderEngine.ResolvedServices; // Note: This method has already taken lock by the caller for resolution and access synchronization. // For root: uses a concurrent dictionary and takes a per singleton lock for resolution. // For scoped: takes a dictionary as both a resolution lock and a dictionary access lock. Debug.Assert( (lockType == RuntimeResolverLock.Root && resolvedServices is ConcurrentDictionary <ServiceCacheKey, object>) || (lockType == RuntimeResolverLock.Scope && Monitor.IsEntered(resolvedServices))); if (resolvedServices.TryGetValue(callSite.Cache.Key, out object resolved)) { return(resolved); } resolved = VisitCallSiteMain(callSite, new RuntimeResolverContext { Scope = serviceProviderEngine, AcquiredLocks = context.AcquiredLocks | lockType }); serviceProviderEngine.CaptureDisposable(resolved); resolvedServices.Add(callSite.Cache.Key, resolved); return(resolved); }