C# 如何查看.NET iSeries Provider可以提供的所有服务?

C# 如何查看.NET iSeries Provider可以提供的所有服务?,c#,.net,C#,.net,这是一个关于.NET的一般性问题 我得到了一个接口的实例,但我几乎没有文档说明可以从中得到什么。如何找到它可能提供的所有服务的列表?这个问题没有通用的解决方案,它取决于您正在使用的实现,如果您可以使用任何方法来查找服务列表。有一个方法,.GetService(Type),它返回单个服务。它本质上是一个将类型映射到服务的字典,并且它不提供对所有键的访问,可能是因为它旨在通过网络实现 由实现接口的类来公开允许发现其提供的服务的方法或属性-仅使用接口无法查看所有提供的服务。 ###解决方案: 如果您

这是一个关于.NET的一般性问题


我得到了一个接口的实例,但我几乎没有文档说明可以从中得到什么。如何找到它可能提供的所有服务的列表?

这个问题没有通用的解决方案,它取决于您正在使用的实现,如果您可以使用任何方法来查找服务列表。

有一个方法,
.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
    实现该接口,但是
    GetService(Type)
    方法仅作为内部使用记录,并且它包含的唯一服务(至少在公共API中)是。无法查询此实现中的所有服务

  • 实际上没有实现接口(尽管它确实具有该接口类型的)。即使
    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);
    }