C# 如何查看.NET iSeries Provider可以提供的所有服务?
这是一个关于.NET的一般性问题C# 如何查看.NET iSeries Provider可以提供的所有服务?,c#,.net,C#,.net,这是一个关于.NET的一般性问题 我得到了一个接口的实例,但我几乎没有文档说明可以从中得到什么。如何找到它可能提供的所有服务的列表?这个问题没有通用的解决方案,它取决于您正在使用的实现,如果您可以使用任何方法来查找服务列表。有一个方法,.GetService(Type),它返回单个服务。它本质上是一个将类型映射到服务的字典,并且它不提供对所有键的访问,可能是因为它旨在通过网络实现 由实现接口的类来公开允许发现其提供的服务的方法或属性-仅使用接口无法查看所有提供的服务。 ###解决方案: 如果您
我得到了一个接口的实例,但我几乎没有文档说明可以从中得到什么。如何找到它可能提供的所有服务的列表?这个问题没有通用的解决方案,它取决于您正在使用的实现,如果您可以使用任何方法来查找服务列表。有一个方法,
.GetService(Type)
,它返回单个服务。它本质上是一个将类型映射到服务的字典,并且它不提供对所有键的访问,可能是因为它旨在通过网络实现
由实现接口的类来公开允许发现其提供的服务的方法或属性-仅使用接口无法查看所有提供的服务。
###解决方案:
- 如果您可以控制服务提供商的源代码,那么创建一个子接口,以允许您所需的内容
interface IBetterServiceProvider : System.IServiceProvider { IList<object> GetAllServices(); IList<Type> GetAllServicedTypes(); }
并让您的服务实现它接口IBetterServiceProvider:System.IServiceProvider { IList GetAllServices(); IList GetAllServicedTypes(); }
- 如果您无法控制服务提供商的源代码,可以强制转换为
实现类型,或者使用反射来查找告诉您所需内容的属性或方法。如果您正在使用的提供程序中似乎存在一致的IServiceProvider
类方法,那么您可以使用动态调度来访问该方法,而无需强制转换.GetServices()
也就是说,即使是微软自己的类实现也有点像兔子洞。引用这些文件 IServiceProvider接口由多种类型实现,包括
System.Web.HttpContext
、System.ComponentModel.LicenseContext
、System.ComponentModel.MarshallByValueComponent
和System.ComponentModel.Design.ServiceContainer
实现该接口,但是HttpContext
方法仅作为内部使用记录,并且它包含的唯一服务(至少在公共API中)是。无法查询此实现中的所有服务GetService(Type)
- 实际上没有实现接口(尽管它确实具有该接口类型的)。即使
没有实现接口,它 是否实现了该方法,以及。它确实证实了怀疑——它是一个美化的字典,将类型映射到服务。同样,这个实现并没有提供它自己的方式来获取它所拥有的所有服务。这是我所期望的,因为它是一个明确的服务容器ServiceContainer
也许这个类的一些子类提供了一种获取所有服务的方法,但是这个类没有LicenseContext.GetService(Type)
我已经完成了对源代码和文档的挖掘。这看起来有点混乱,但上面的简短回答是:旧名称或新名称、伪实现或实际实现:无法仅从
IServiceProvider
接口获取所有服务,我发现的微软的任何一个实现都不能让你做到这一点。对于我的应用程序,我想一次迁移所有的dbcontext
。因此,在配置了IServiceCollection
并构建了IServiceProvider
之后,我没有机会通过IServiceProvider
访问它们
下面的代码片段可以做到这一点,但是:
这是一项非常实验性的工作,因此应执行UnitTest
,以记录Microsoft的更改,并相应地调整方法强>
公共静态类IServiceProviderExtensions
{
///
///登记
///
///
///
公共静态字典GetAllServiceDescriptors(此IServiceProvider提供程序)
{
如果(提供程序是服务提供程序服务提供程序)
{
var result=newdictionary();
var engine=serviceProvider.GetFieldValue(“_engine”);
var callSiteFactory=engine.GetPropertyValue(“callSiteFactory”);
var descriptorLookup=callSiteFactory.GetFieldValue(“_descriptorLookup”);
if(描述符lookup是字典)
{
foreach(字典在字典中输入条目)
{
Add((Type)entry.Key,(servicescriptor)entry.Value.GetPropertyValue(“Last”));
}
}
返回结果;
}
抛出新的NotSupportedException($“不支持类型“{provider.GetType()}”);
}
}
公共静态类ReflectionHelper
{
// ##########################################################################################
//获取/设置字段
// ##########################################################################################
#区域获取/设置字段
公共静态对象GetFieldValue(此对象对象对象,字符串字段名)
{
if(obj==null)
抛出新ArgumentNullException(nameof(obj));
类型objType=obj.GetType();
var fieldInfo=GetFieldInfo(对象类型,字段名);
如果(fieldInfo==null)
抛出新ArgumentOutOfRangeException(字段名,
$“在类型{objType.FullName}”中找不到字段{fieldName}”;
返回fieldInfo.GetValue(obj);
}
公共静态void SetFieldValue(此对象对象对象、字符串字段名、对象值)
{
if(obj==null)
抛出新ArgumentNullException(nameof(obj));
类型objType=obj.GetType();
var fieldInfo=GetFieldInfo(对象类型,fieldNa
public static class DiExtension
{
private static IServiceCollection _serviceCollection;
public static void AddServiceCollection(this IServiceProvider services, IServiceCollection serviceCollection)
{
_serviceCollection = serviceCollection;
}
public static bool HasService(this IServiceProvider services, Type serviceType)
{
return _serviceCollection.Any(s => s.ServiceType.FullName == serviceType.FullName);
}
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, Domain.Logging.ILogger logger, IServiceProvider serviceProvider)
{
// Notice that I inject IServiceProvider into the method
serviceProvider.AddServiceCollection(_serviceCollection);
}
public void ConfigureServices(IServiceCollection services)
{
// register all the things you need
_serviceCollection = services;
}
public class SomeClass
{
private readonly IServiceProvider _serviceProvider;
public SomeClass(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public void SomeMethod(Type service)
{
var hasType = _serviceProvider.HasService(service);
// Do what you have to do...
}
}
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSingleton(services);
}