NewLife/X

从对象容器创建服务提供者,支持传入另一个服务提供者作为内部提供者
大石头 编写于 2024-10-29 10:02:24
共计: 修改3个文件,增加19行、删除14行。
修改 +0 -4
修改 +10 -7
修改 +9 -3
修改 +0 -4
diff --git a/NewLife.Core/Model/Host.cs b/NewLife.Core/Model/Host.cs
index 30991ce..c600920 100644
--- a/NewLife.Core/Model/Host.cs
+++ b/NewLife.Core/Model/Host.cs
@@ -85,7 +85,6 @@ public class Host : DisposeBase, IHost
     /// <summary>服务提供者</summary>
     public IServiceProvider ServiceProvider { get; set; }
 
-    //private readonly IList<Type> _serviceTypes = new List<Type>();
     /// <summary>服务集合</summary>
     public IList<IHostedService> Services { get; } = [];
     #endregion
@@ -125,9 +124,6 @@ public class Host : DisposeBase, IHost
     /// <typeparam name="TService"></typeparam>
     public void Add<TService>() where TService : class, IHostedService
     {
-        //var type = typeof(TService);
-        //_serviceTypes.Add(type);
-
         // 把服务类型注册到容器中,以便后续获取
         var ioc = (ServiceProvider as ServiceProvider)?.Container ?? ObjectContainer.Current;
         //ioc.TryAddTransient(type, type);
修改 +10 -7
diff --git a/NewLife.Core/Model/ObjectContainer.cs b/NewLife.Core/Model/ObjectContainer.cs
index 04b663f..c45d0c7 100644
--- a/NewLife.Core/Model/ObjectContainer.cs
+++ b/NewLife.Core/Model/ObjectContainer.cs
@@ -21,12 +21,12 @@ public class ObjectContainer : IObjectContainer
     {
         var ioc = new ObjectContainer();
         Current = ioc;
-        Provider = ioc.BuildServiceProvider() ?? new ServiceProvider(ioc);
+        Provider = ioc.BuildServiceProvider();
     }
     #endregion
 
     #region 属性
-    private readonly IList<IObject> _list = new List<IObject>();
+    private readonly IList<IObject> _list = [];
     /// <summary>服务集合</summary>
     public IList<IObject> Services => _list;
 
@@ -126,7 +126,7 @@ public class ObjectContainer : IObjectContainer
         if (item.Lifetime == ObjectLifetime.Singleton && map?.Instance != null) return map.Instance;
 
         var type = item.ImplementationType ?? item.ServiceType;
-        serviceProvider ??= new ServiceProvider(this);
+        serviceProvider ??= new ServiceProvider(this, null);
         switch (item.Lifetime)
         {
             case ObjectLifetime.Singleton:
@@ -287,13 +287,13 @@ public class ServiceDescriptor : IObject
     #endregion
 }
 
-internal class ServiceProvider : IServiceProvider
+internal class ServiceProvider(IObjectContainer container, IServiceProvider? innerServiceProvider) : IServiceProvider
 {
-    private readonly IObjectContainer _container;
+    private readonly IObjectContainer _container = container;
     /// <summary>容器</summary>
     public IObjectContainer Container => _container;
 
-    public ServiceProvider(IObjectContainer container) => _container = container;
+    public IServiceProvider? InnerServiceProvider { get; set; } = innerServiceProvider;
 
     public Object? GetService(Type serviceType)
     {
@@ -311,6 +311,9 @@ internal class ServiceProvider : IServiceProvider
             });
         }
 
-        return _container.Resolve(serviceType, this);
+        var service = _container.Resolve(serviceType, this);
+        if (service != null) return service;
+
+        return InnerServiceProvider?.GetService(serviceType);
     }
 }
\ No newline at end of file
修改 +9 -3
diff --git a/NewLife.Core/Model/ObjectContainerHelper.cs b/NewLife.Core/Model/ObjectContainerHelper.cs
index b31cbbe..e664a45 100644
--- a/NewLife.Core/Model/ObjectContainerHelper.cs
+++ b/NewLife.Core/Model/ObjectContainerHelper.cs
@@ -362,16 +362,22 @@ public static class ObjectContainerHelper
 
     #region 构建
     /// <summary>从对象容器创建服务提供者</summary>
-    /// <param name="container"></param>
+    /// <param name="container">对象容器</param>
+    /// <returns></returns>
+    public static IServiceProvider BuildServiceProvider(this IObjectContainer container) => BuildServiceProvider(container, null);
+
+    /// <summary>从对象容器创建服务提供者,支持传入另一个服务提供者作为内部提供者</summary>
+    /// <param name="container">对象容器</param>
+    /// <param name="innerServiceProvider">内部服务提供者,常用于NETCore的IoC</param>
     /// <returns></returns>
-    public static IServiceProvider BuildServiceProvider(this IObjectContainer container)
+    public static IServiceProvider BuildServiceProvider(this IObjectContainer container, IServiceProvider? innerServiceProvider)
     {
         if (container == null) throw new ArgumentNullException(nameof(container));
 
         var provider = container.Resolve(typeof(IServiceProvider)) as IServiceProvider;
         if (provider != null) return provider;
 
-        var provider2 = new ServiceProvider(container);
+        var provider2 = new ServiceProvider(container, innerServiceProvider);
 
         container.TryAddSingleton(provider2);