重新整理.net core 计1400篇[九] (.net core 中的依赖注入的服务的消费)

2021-02-18 22:19

阅读:503

标签:root   reference   如何   build   interface   信息   create   missing   services   

前言

包含服务注册信息IServiceCollection 集合最终被用来创建作为依赖注入容器的IServiceProvider 对象。

当需要创建某个服务实例的时候(服务消费),我们通过指定服务类型调用IServiceProvider 接口GetService 方法即可。

那么来看下和IServiceProvider 相关的东西吧。

IServiceProvider

这里面只有一个提供服务的方法:

/// Defines a mechanism for retrieving a service object; that is, an object that provides custom support to other objects.
public interface IServiceProvider
{
	/// Gets the service object of the specified type.
	/// An object that specifies the type of service object to get.
	/// A service object of type serviceType.  
	///  -or-  
	///  null if there is no service object of type serviceType.
	object GetService(Type serviceType);
}

在创建IServiceProvider的对象创建上,有三个构造函数:

public static class ServiceCollectionContainerBuilderExtensions
{
	/// 
	/// Creates a  containing services from the provided .
	/// 
	/// The  containing service descriptors.
	/// The .
	public static ServiceProvider BuildServiceProvider(this IServiceCollection services)
	{
		return services.BuildServiceProvider(ServiceProviderOptions.Default);
	}

	/// 
	/// Creates a  containing services from the provided 
	/// optionally enabling scope validation.
	/// 
	/// The  containing service descriptors.
	/// 
	/// true to perform check verifying that scoped services never gets resolved from root provider; otherwise false.
	/// 
	/// The .
	public static ServiceProvider BuildServiceProvider(this IServiceCollection services, bool validateScopes)
	{
		return services.BuildServiceProvider(new ServiceProviderOptions
		{
			ValidateScopes = validateScopes
		});
	}

	/// 
	/// Creates a  containing services from the provided 
	/// optionally enabling scope validation.
	/// 
	/// The  containing service descriptors.
	/// 
	/// Configures various service provider behaviors.
	/// 
	/// The .
	public static ServiceProvider BuildServiceProvider(this IServiceCollection services, ServiceProviderOptions options)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		if (services == null)
		{
			throw new ArgumentNullException("services");
		}
		if (options == null)
		{
			throw new ArgumentNullException("options");
		}
		return new ServiceProvider((IEnumerable)services, options);
	}
}

我们看到无论其如何构造,那么都有一个ServiceProviderOptions配置类。

这个配置我前面8中解释过,就是对注入服务的范围检测。

那么还有一个重要的问题,难道我们只能根据getservice 去获取服务对象?来看看获取服务的扩展。

查看ServiceProviderServiceExtensions类:

里面有一些:

public static T GetService(this IServiceProvider provider)
{
	//IL_0008: Unknown result type (might be due to invalid IL or missing references)
	if (provider == null)
	{
		throw new ArgumentNullException("provider");
	}
	return (T)provider.GetService(Type.GetTypeFromHandle(typeof(T).TypeHandle));
}

/// 
/// Get service of type  from the .
/// 
/// The  to retrieve the service object from.
/// An object that specifies the type of service object to get.
/// A service object of type .
/// There is no service of type .
public static object GetRequiredService(this IServiceProvider provider, Type serviceType)
{
	//IL_0008: Unknown result type (might be due to invalid IL or missing references)
	//IL_001c: Unknown result type (might be due to invalid IL or missing references)
	//IL_0044: Unknown result type (might be due to invalid IL or missing references)
	if (provider == null)
	{
		throw new ArgumentNullException("provider");
	}
	if (serviceType == (Type)null)
	{
		throw new ArgumentNullException("serviceType");
	}
	ISupportRequiredService supportRequiredService = provider as ISupportRequiredService;
	if (supportRequiredService != null)
	{
		return supportRequiredService.GetRequiredService(serviceType);
	}
	object service = provider.GetService(serviceType);
	if (service == null)
	{
		throw new InvalidOperationException(Resources.FormatNoServiceRegistered(serviceType));
	}
	return service;
}

/// 
/// Get service of type  from the .
/// 
/// The type of service object to get.
/// The  to retrieve the service object from.
/// A service object of type .
/// There is no service of type .
public static T GetRequiredService(this IServiceProvider provider)
{
	//IL_0008: Unknown result type (might be due to invalid IL or missing references)
	if (provider == null)
	{
		throw new ArgumentNullException("provider");
	}
	return (T)provider.GetRequiredService(Type.GetTypeFromHandle(typeof(T).TypeHandle));
}

/// 
/// Get an enumeration of services of type  from the .
/// 
/// The type of service object to get.
/// The  to retrieve the services from.
/// An enumeration of services of type .
public static IEnumerable GetServices(this IServiceProvider provider)
{
	//IL_0008: Unknown result type (might be due to invalid IL or missing references)
	if (provider == null)
	{
		throw new ArgumentNullException("provider");
	}
	return provider.GetRequiredService>();
}

其余的可以自己去查看。

服务的创建

我们知道服务的创建一般都是ioc自动选择的,那么假如我们一个class 里面有多个构造函数,那么会选择哪一个呢?

public interface IFoo { }
public interface IBar { }
public interface IBaz { }
public interface IQux { }

public class Foo : IFoo { }
public class Bar : IBar { }
public class Baz : IBaz { }
public class Qux : IQux
{
	public Qux(IFoo foo) => Console.WriteLine("Selected constructor: Qux(IFoo)");
	public Qux(IFoo foo, IBar bar) => Console.WriteLine("Selected constructor: Qux(IFoo, IBar)");
	public Qux(IFoo foo, IBar bar, IBaz baz) => Console.WriteLine("Selected constructor: Qux(IFoo, IBar, IBaz)");
}
static void Main()
{
	new ServiceCollection()
		.AddTransient()
		.AddTransient()
		.AddTransient()
		.BuildServiceProvider()
		.GetServices();
	Console.ReadKey();
}

上面Qux有三个控制类,那么选择哪一个呢?

看下结果:

技术图片

那么为什么会是这一个呢?

第一:IBaz类型没有注册,那么会排除掉Qux(IFoo foo, IBar bar, IBaz baz)

第二就是里面的一个规则:每一个候选构造参数类型的集合都是这个构造函数参数类型的子集。

好的,那么好了,剩下:Qux(IFoo foo, IBar bar) 包含了Qux(IFoo foo) 那么就是Qux(IFoo foo, IBar bar),如果没有包含全部子集的那么就会报错。

Qux(IFoo foo, IBar bar) 也就是超集的意思。

改一下:

public interface IFoo { }
public interface IBar { }
public interface IBaz { }
public interface IQux { }

public class Foo : IFoo { }
public class Bar : IBar { }
public class Baz : IBaz { }
public class Qux : IQux
{
	public Qux(IFoo foo, IBaz baz) => Console.WriteLine("Selected constructor: Qux(IFoo, IBar)");
	public Qux(IFoo foo, IBar bar) => Console.WriteLine("Selected constructor: Qux(IFoo, IBar, IBaz)");
}
static void Main()
{
	new ServiceCollection()
		.AddTransient()
		.AddTransient()
		.AddTransient()
		.AddTransient()
		.BuildServiceProvider()
		.GetServices();
	Console.ReadKey();
}

这时候报错为:

技术图片

下一节

服务的生命周期

重新整理.net core 计1400篇[九] (.net core 中的依赖注入的服务的消费)

标签:root   reference   如何   build   interface   信息   create   missing   services   

原文地址:https://www.cnblogs.com/aoximin/p/12931943.html


评论


亲,登录后才可以留言!