【问题标题】:How to DI repository into Type-class?如何将 DI 存储库转换为 Type-class?
【发布时间】:2018-11-11 14:28:28
【问题描述】:

这里需要一些帮助...

我正在查看示例“graphql-dotnet/server”,其中公开的对象仅包含普通属性。但是如果我需要解析一个属性并从存储库中获取数据,我该如何获取 Type-class 中的存储库类呢?

示例: 该示例有一个 ChatQuery 公开“消息”。

public ChatQuery(IChat chat)
    {
        Field<ListGraphType<MessageType>>("messages", resolve: context => chat.AllMessages.Take(100));
    }

实例“chat”是此处的存储库,通过 chat.AllMessages 提供数据(消息)。

假设一条消息有一个查看者列表。然后我需要从存储库中解析该列表。这是在另一个示例“graphql-dotnet/examples”中完成的,其中“StarWars/Types/StarWarsCharacter.cs”有一个朋友列表,而“ StarWars/Types/HumanType”在构造函数中插入了存储库(StarWarsData),可以在“friends”的resolve方法中使用:

public class HumanType : ObjectGraphType<Human>
{
    public HumanType(StarWarsData data)
    {
        Name = "Human";

        Field(h => h.Id).Description("The id of the human.");
        Field(h => h.Name, nullable: true).Description("The name of the human.");

        Field<ListGraphType<CharacterInterface>>(
            "friends",
            resolve: context => data.GetFriends(context.Source)
        );
        Field<ListGraphType<EpisodeEnum>>("appearsIn", "Which movie they appear in.");

        Field(h => h.HomePlanet, nullable: true).Description("The home planet of the human.");

        Interface<CharacterInterface>();
    }
}

但是,在服务器示例中做同样的事情是行不通的。

public class MessageType : ObjectGraphType<Message>
{
    public MessageType(IChat chat)
    {
        Field(o => o.Content);
        Field(o => o.SentAt);
        Field(o => o.From, false, typeof(MessageFromType)).Resolve(ResolveFrom);
        Field<ListGraphType<Viewer>>(
            "viewers",
            resolve: context => chat.GetViewers(context.Source)
        );
    }

    private MessageFrom ResolveFrom(ResolveFieldContext<Message> context)
    {
        var message = context.Source;
        return message.From;
    }
}

当我将聊天存储库添加到 MessageType 中的构造函数时,它失败了。

我显然在这里遗漏了一些东西;为什么依赖注入不将聊天实例注入“graphql-dotnet/server”项目中的 MessageType 类? 但它适用于“graphql-dotnet/examples”项目。

最好, 马格努斯

【问题讨论】:

    标签: dependency-injection graphql graphql-dotnet


    【解决方案1】:

    要使用 DI,您需要在 Schema 类的构造函数中传递依赖解析器。默认解析器使用Activator.CreateInstance,所以你必须教它你正在使用的容器。

    services.AddSingleton<IDependencyResolver>(
      s => new FuncDependencyResolver(s.GetRequiredService));
    

    IDependecyResolver是graphql-dotnet项目中的一个接口。

    public class StarWarsSchema : Schema
    {
        public StarWarsSchema(IDependencyResolver resolver)
            : base(resolver)
        {
            Query = resolver.Resolve<StarWarsQuery>();
            Mutation = resolver.Resolve<StarWarsMutation>();
        }
    }
    

    https://github.com/graphql-dotnet/examples/blob/bcf46c5c502f8ce75022c50b9b23792e5146f6d2/src/AspNetCore/Example/Startup.cs#L20

    https://github.com/graphql-dotnet/examples/blob/bcf46c5c502f8ce75022c50b9b23792e5146f6d2/src/StarWars/StarWarsSchema.cs#L6-L14

    【讨论】:

      猜你喜欢
      • 2020-01-03
      • 2018-01-03
      • 1970-01-01
      • 1970-01-01
      • 2011-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-18
      相关资源
      最近更新 更多