【问题标题】:.NET Core - resolving IServiceProvider dependency.NET Core - 解决 IServiceProvider 依赖项
【发布时间】:2020-06-26 05:04:16
【问题描述】:

我将 GraphQL 2.4.0 与 .NET Core 3.1 解决方案和 Microsoft DI 一起使用。 我的Schema.cs 看起来像:

public class MySchema : GraphQL.Types.Schema
{
    private ISchema _schema { get; set; }
    public ISchema GraphQLSchema
    {
        get
        {
            return this._schema;
        }
    }

    public MySchema(IServiceProvider sp)
    {
        this._schema = Schema.For(@"
            type MyObj{
                id: ID
                name: String,
                type: String,
                createdAt: String
            }

            type Mutation {
                objSync(type: String): MyObj
            }

            type Query {
                myobj: MyObj
            }
        ", _ =>
        {
            _.DependencyResolver = new FuncDependencyResolver(t => sp.GetService(t)); // Since I'm using v2.4
            _.Types.Include<MyQuery>();
            _.Types.Include<MyMutation>();
        });
    }
}

MyMutation.cs 看起来像:

[GraphQLMetadata("MyMutation")]
public class MyMutation
{
    private readonly ISomeType someType;

    public MyMutation(ISomeType someType)
    {
        this.someType= someType;
    }

    [GraphQLMetadata("objSync")]
    public MyObj SyncObj(string type)
    {
        byte[] _bytes = null;
        _bytes = someType.Process(type).Result;
        return new Obj { File = Encoding.UTF8.GetString(_bytes , 0, _bytes .Length) };
    }
}

我正在解决依赖项Startup.cs,例如:

...
public static void AddServices(this IServiceCollection services)
{
    services.AddSingleton<IDependencyResolver>(_ => new FuncDependencyResolver(_.GetRequiredService));
    services.AddSingleton<IDocumentExecuter, DocumentExecuter>();
    services.AddSingleton<IDocumentWriter, DocumentWriter>();
    services.AddSingleton<MyMutation>();
    services.AddSingleton<IServiceProvider>();
    services.AddScoped<ISchema, MySchema>();
    services.AddSingleton<ISomeType, SomeManager>();
    ...
}
...

我在GraphQLController.cs 中以下列方式使用架构:

[Route("graphql")]
[ApiController]
public class GraphQLController: ControllerBase
{
    MySchema schema;
    IServiceProvider serviceProvider;

    public GraphQLController(IServiceProvider serviceProvider)
    {
        schema = new MySchema(serviceProvider);
    }

    [HttpPost]
    public ActionResult Post([FromBody] GraphQLQuery query)
    {
        try
        {
            var inputs = query.Variables.ToInputs();

            var result = new DocumentExecuter().ExecuteAsync(_ =>
            {
                _.Schema = schema.GraphQLSchema;
                _.Query = query.Query;
                _.OperationName = query.OperationName;
                _.Inputs = inputs;
            }).Result;

            if (result.Errors?.Count > 0)
            {
                return BadRequest();
            }

            return Ok(result);
        }
        catch (Exception ex)
        {
            return BadRequest();
        }
    }
}

通过上述设置,我得到一个异常:

Unhandled exception. System.ArgumentException: Cannot instantiate implementation type 'System.IServiceProvider' for service type 'System.IServiceProvider'.
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.Populate()
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory..ctor(IEnumerable`1 descriptors)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine..ctor(IEnumerable`1 serviceDescriptors, IServiceProviderEngineCallback callback)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CompiledServiceProviderEngine..ctor(IEnumerable`1 serviceDescriptors, IServiceProviderEngineCallback callback)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable`1 serviceDescriptors, ServiceProviderOptions options)
   at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options)
   at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.WebHost.Initialize()
   at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
   at App.Api.Program.Main(String[] args)

问题:所以MySchema 需要IServiceProvider 输入,如果我必须实例化它。我如何实例化它?还是有其他方法可以调用MySchema

【问题讨论】:

    标签: c# .net .net-core dependency-injection graphql


    【解决方案1】:

    删除这一行:

    services.AddSingleton<IServiceProvider>();
    

    你不能注册一个接口,你必须注册一个类或结构,但最重要的是,IServiceProvider 已经被框架交给了。您不需要向您的服务提供商注册服务提供商

    当我们在做的时候:

    public GraphQLController(IServiceProvider serviceProvider)
    {
        schema = new MySchema(serviceProvider);
    }
    

    如果您使用 DI,请不要手动操作:

    public GraphQLController(IMySchema schema)
    {
        this.schema = schema; // this.schema needs to be IMySchema as well
    }
    

    【讨论】:

    • 感谢您的回答。你对ISeriviceProvider 所说的话是有道理的。现在在将MySchema schema 传递给构造函数时,DI 将如何解决它?
    • 哦,对不起,你是对的,你需要通过IMySchema,你注册了它:services.AddScoped&lt;ISchema, MySchema&gt;();
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多