public OrganizationType(IMediator mediator)
        {
            Name        = "Organization";
            Description = "Organization info";
            //this.AuthorizeWith(CustomerModule.Core.ModuleConstants.Security.Permissions.Read);

            Field(x => x.Organization.Id).Description("Description");
            Field(x => x.Organization.Description, true).Description("Description");
            Field(x => x.Organization.BusinessCategory, true).Description("Business category");
            Field(x => x.Organization.OwnerId, true).Description("Owner id");
            Field(x => x.Organization.ParentId, true).Description("Parent id");
            Field(x => x.Organization.Name, true).Description("Name");
            Field(x => x.Organization.MemberType).Description("Member type");
            Field(x => x.Organization.OuterId, true).Description("Outer id");
            Field <NonNullGraphType <ListGraphType <MemberAddressType> > >("addresses", resolve: x => x.Source.Organization.Addresses);
            Field(x => x.Organization.Phones, true);
            Field(x => x.Organization.Emails, true);
            Field(x => x.Organization.Groups, true);
            Field(x => x.Organization.SeoObjectType).Description("SEO object type");

            // TODO:
            //DynamicProperties
            //    SeoInfos

            var connectionBuilder = GraphTypeExtenstionHelper.CreateConnection <ContactType, OrganizationAggregate>()
                                    .Name("contacts")
                                    .Argument <StringGraphType>("searchPhrase", "Free text search")
                                    .Unidirectional()
                                    .PageSize(20);

            connectionBuilder.ResolveAsync(async context => await ResolveConnectionAsync(mediator, context));
            AddField(connectionBuilder.FieldType);
        }
        public void Build(ISchema schema)
        {
            var connectionBuilder = GraphTypeExtenstionHelper.CreateConnection <ProductRecommendationType, object>()
                                    .Name("recommendations")
                                    .Argument <StringGraphType>("scenario", "The recommendation scenario")
                                    .Argument <StringGraphType>("itemId", "The context product id")
                                    .Argument <StringGraphType>("userId", "The context user id")
                                    .Unidirectional()
                                    .PageSize(20);

            connectionBuilder.ResolveAsync(async context =>
            {
                return(await ResolveConnectionAsync(context));
            });
            schema.Query.AddField(connectionBuilder.FieldType);
        }
Пример #3
0
        public void Build(ISchema schema)
        {
            var dynamicPropertyField = new FieldType
            {
                Name      = "dynamicProperty",
                Arguments = new QueryArguments(
                    new QueryArgument <NonNullGraphType <StringGraphType> > {
                    Name = "idOrName", Description = "Id or name of the dynamic property"
                },
                    new QueryArgument <StringGraphType> {
                    Name = "cultureName", Description = "Culture name (\"en-US\")"
                },
                    new QueryArgument <StringGraphType> {
                    Name = "objectType", Description = "Object type of the dynamic property"
                }
                    ),
                Type     = GraphTypeExtenstionHelper.GetActualType <DynamicPropertyType>(),
                Resolver = new AsyncFieldResolver <object>(async context =>
                {
                    context.CopyArgumentsToUserContext();

                    var query        = context.GetDynamicPropertiesQuery <GetDynamicPropertyQuery>();
                    query.IdOrName   = context.GetArgument <string>("idOrName");
                    query.ObjectType = context.GetArgument <string>("objectType");

                    var response = await _mediator.Send(query);

                    return(response.DynamicProperty);
                })
            };

            schema.Query.AddField(dynamicPropertyField);

            var dynamicPropertiesConnectionBuilder = GraphTypeExtenstionHelper.CreateConnection <DynamicPropertyType, object>()
                                                     .Name("dynamicProperties")
                                                     .Argument <StringGraphType>("cultureName", "The culture name (\"en-US\")")
                                                     .Argument <StringGraphType>("filter", "This parameter applies a filter to the query results")
                                                     .Argument <StringGraphType>("sort", "The sort expression")
                                                     .Argument <StringGraphType>("objectType", "Object type of the dynamic property")
                                                     .PageSize(20);

            dynamicPropertiesConnectionBuilder.ResolveAsync(async context => await ResolveDynamicPropertiesConnectionAsync(_mediator, context));

            schema.Query.AddField(dynamicPropertiesConnectionBuilder.FieldType);
        }
Пример #4
0
        public void Build(ISchema schema)
        {
            var connectionBuilder = GraphTypeExtenstionHelper.CreateConnection <ProductRecommendationType, object>()
                                    .Name("recommendations")
                                    .Argument <StringGraphType>("scenario", "The recommendation scenario")
                                    .Argument <StringGraphType>("itemId", "The context product id")
                                    .Argument <StringGraphType>("userId", "The context user id")
                                    .Argument <StringGraphType>("storeId", "the store id")
                                    .PageSize(20);

            connectionBuilder.ResolveAsync(async context =>
            {
                //PT-1606:  Need to check what there is no any alternative way to access to the original request arguments in sub selection
                context.CopyArgumentsToUserContext();
                return(await ResolveConnectionAsync(context));
            });
            schema.Query.AddField(connectionBuilder.FieldType);
        }
        public void Build(ISchema schema)
        {
            var productField = new FieldType
            {
                Name      = "product",
                Arguments = new QueryArguments(new QueryArgument <NonNullGraphType <StringGraphType> > {
                    Name = "id", Description = "id of the product"
                }),
                Type     = GraphTypeExtenstionHelper.GetActualType <ProductType>(),
                Resolver = new AsyncFieldResolver <object>(async context =>
                {
                    var loader = _dataLoader.Context.GetOrAddBatchLoader <string, ExpProduct>("productsLoader", (ids) => LoadProductsAsync(_mediator, ids, context.SubFields.Values.GetAllNodesPaths()));
                    return(await loader.LoadAsync(context.GetArgument <string>("id")));
                })
            };

            schema.Query.AddField(productField);

            //var productsConnectionBuilder = ConnectionBuilder.Create<ProductType, EdgeType<ProductType>, ProductsConnectonType<ProductType>, object>()
            var productsConnectionBuilder = GraphTypeExtenstionHelper.CreateConnection <ProductType, EdgeType <ProductType>, ProductsConnectonType <ProductType>, object>()
                                            .Name("products")
                                            .Argument <StringGraphType>("query", "The query parameter performs the full-text search")
                                            .Argument <StringGraphType>("filter", "This parameter applies a filter to the query results")
                                            .Argument <BooleanGraphType>("fuzzy", "When the fuzzy query parameter is set to true the search endpoint will also return products that contain slight differences to the search text.")
                                            .Argument <StringGraphType>("facet", "Facets calculate statistical counts to aid in faceted navigation.")
                                            .Argument <StringGraphType>("sort", "The sort expression")
                                            .Unidirectional()
                                            .PageSize(20);

            productsConnectionBuilder.ResolveAsync(async context =>
            {
                return(await ResolveConnectionAsync(_mediator, context));
            });


            schema.Query.AddField(productsConnectionBuilder.FieldType);
        }
        /// <summary>
        /// XDigitalCatalog schema builder
        /// </summary>
        /// <remarks>
        /// IMPORTANT!
        /// We can't use the fluent syntax for new types registration provided by dotnet graphql here,
        /// because we have the strict requirement for underlying types extensions and must use
        /// GraphTypeExtenstionHelper to resolve the effective type on execution time
        /// </remarks>
        public void Build(ISchema schema)
        {
            var productField = new FieldType
            {
                Name      = "product",
                Arguments = new QueryArguments(
                    new QueryArgument <NonNullGraphType <StringGraphType> > {
                    Name = "id", Description = "id of the product"
                },
                    new QueryArgument <NonNullGraphType <StringGraphType> > {
                    Name = "storeId", Description = "Store Id"
                },
                    new QueryArgument <StringGraphType> {
                    Name = "userId", Description = "User Id"
                },
                    new QueryArgument <StringGraphType> {
                    Name = "currencyCode", Description = "Currency code (\"USD\")"
                },
                    new QueryArgument <StringGraphType> {
                    Name = "cultureName", Description = "Culture name (\"en-US\")"
                }
                    ),
                Type     = GraphTypeExtenstionHelper.GetActualType <ProductType>(),
                Resolver = new AsyncFieldResolver <object, IDataLoaderResult <ExpProduct> >(async context =>
                {
                    //PT-1606:  Need to check what there is no any alternative way to access to the original request arguments in sub selection
                    context.CopyArgumentsToUserContext();

                    var store = await _storeService.GetByIdAsync(context.GetArgument <string>("storeId"));
                    context.UserContext["store"] = store;

                    var cultureName = context.GetArgument <string>("cultureName");

                    var allCurrencies = await _currencyService.GetAllCurrenciesAsync();
                    //Store all currencies in the user context for future resolve in the schema types
                    context.SetCurrencies(allCurrencies, cultureName);

                    var loader = _dataLoader.Context.GetOrAddBatchLoader <string, ExpProduct>("productsLoader", (ids) => LoadProductsAsync(_mediator, ids, context));
                    return(loader.LoadAsync(context.GetArgument <string>("id")));
                })
            };

            schema.Query.AddField(productField);

            var productsConnectionBuilder = GraphTypeExtenstionHelper.CreateConnection <ProductType, EdgeType <ProductType>, ProductsConnectonType <ProductType>, object>()
                                            .Name("products")
                                            .Argument <NonNullGraphType <StringGraphType> >("storeId", "The store id where products are searched")
                                            .Argument <StringGraphType>("userId", "The customer id for search result impersonalization")
                                            .Argument <StringGraphType>("currencyCode", "The currency for which all prices data will be returned")
                                            .Argument <StringGraphType>("cultureName", "The culture name for cart context product")
                                            .Argument <StringGraphType>("query", "The query parameter performs the full-text search")
                                            .Argument <StringGraphType>("filter", "This parameter applies a filter to the query results")
                                            .Argument <BooleanGraphType>("fuzzy", "When the fuzzy query parameter is set to true the search endpoint will also return products that contain slight differences to the search text.")
                                            .Argument <IntGraphType>("fuzzyLevel", "The fuzziness level is quantified in terms of the Damerau-Levenshtein distance, this distance being the number of operations needed to transform one word into another.")
                                            .Argument <StringGraphType>("facet", "Facets calculate statistical counts to aid in faceted navigation.")
                                            .Argument <StringGraphType>("sort", "The sort expression")
                                            .Argument <ListGraphType <StringGraphType> >("productIds", "Product Ids")
                                            .PageSize(20);

            productsConnectionBuilder.ResolveAsync(async context =>
            {
                //PT-1606:  Need to check what there is no any alternative way to access to the original request arguments in sub selection
                context.CopyArgumentsToUserContext();

                var cultureName = context.GetArgument <string>("cultureName");
                var store       = await _storeService.GetByIdAsync(context.GetArgument <string>("storeId"));
                context.UserContext["store"]   = store;
                context.UserContext["catalog"] = store.Catalog;

                var allCurrencies = await _currencyService.GetAllCurrenciesAsync();
                //Store all currencies in the user context for future resolve in the schema types
                context.SetCurrencies(allCurrencies, cultureName);

                return(await ResolveProductsConnectionAsync(_mediator, context));
            });

            schema.Query.AddField(productsConnectionBuilder.FieldType);

            var categoryField = new FieldType
            {
                Name      = "category",
                Arguments = new QueryArguments(
                    new QueryArgument <NonNullGraphType <StringGraphType> > {
                    Name = "id", Description = "id of the product"
                },
                    new QueryArgument <NonNullGraphType <StringGraphType> > {
                    Name = "storeId", Description = "Store Id"
                },
                    new QueryArgument <StringGraphType> {
                    Name = "userId", Description = "User Id"
                },
                    new QueryArgument <StringGraphType> {
                    Name = "currencyCode", Description = "Currency code (\"USD\")"
                },
                    new QueryArgument <StringGraphType> {
                    Name = "cultureName", Description = "Culture name (\"en-US\")"
                }
                    ),
                Type     = GraphTypeExtenstionHelper.GetActualType <CategoryType>(),
                Resolver = new AsyncFieldResolver <ExpCategory, IDataLoaderResult <ExpCategory> >(async context =>
                {
                    var store = await _storeService.GetByIdAsync(context.GetArgument <string>("storeId"));
                    context.UserContext["store"] = store;

                    //PT-1606:  Need to check what there is no any alternative way to access to the original request arguments in sub selection
                    context.CopyArgumentsToUserContext();

                    var loader = _dataLoader.Context.GetOrAddBatchLoader <string, ExpCategory>("categoriesLoader", (ids) => LoadCategoriesAsync(_mediator, ids, context));
                    return(loader.LoadAsync(context.GetArgument <string>("id")));
                })
            };

            schema.Query.AddField(categoryField);

            var categoriesConnectionBuilder = GraphTypeExtenstionHelper.CreateConnection <CategoryType, object>()
                                              .Name("categories")
                                              .Argument <StringGraphType>("storeId", "The store id where category are searched")
                                              .Argument <StringGraphType>("cultureName", "The language for which all localized category data will be returned")
                                              .Argument <StringGraphType>("userId", "The customer id for search result impersonalization")
                                              .Argument <StringGraphType>("currencyCode", "The currency for which all prices data will be returned")
                                              .Argument <StringGraphType>("query", "The query parameter performs the full-text search")
                                              .Argument <StringGraphType>("filter", "This parameter applies a filter to the query results")
                                              .Argument <BooleanGraphType>("fuzzy", "When the fuzzy query parameter is set to true the search endpoint will also return Categorys that contain slight differences to the search text.")
                                              .Argument <IntGraphType>("fuzzyLevel", "The fuzziness level is quantified in terms of the Damerau-Levenshtein distance, this distance being the number of operations needed to transform one word into another.")
                                              .Argument <StringGraphType>("facet", "Facets calculate statistical counts to aid in faceted navigation.")
                                              .Argument <StringGraphType>("sort", "The sort expression")
                                              .Argument <ListGraphType <StringGraphType> >("categoryIds", "Category Ids")
                                              .PageSize(20);

            categoriesConnectionBuilder.ResolveAsync(async context =>
            {
                var store = await _storeService.GetByIdAsync(context.GetArgument <string>("storeId"));
                context.UserContext["store"] = store;

                //PT-1606:  Need to check what there is no any alternative way to access to the original request arguments in sub selection
                context.CopyArgumentsToUserContext();
                return(await ResolveCategoriesConnectionAsync(_mediator, context));
            });

            schema.Query.AddField(categoriesConnectionBuilder.FieldType);

            var propertiesConnectionBuilder = GraphTypeExtenstionHelper.CreateConnection <PropertyType, object>()
                                              .Name("properties")
                                              .Argument <NonNullGraphType <StringGraphType> >("storeId", "The store id to get binded catalog")
                                              .Argument <ListGraphType <PropertyTypeEnum> >("types", "The owner types (Catalog, Category, Product, Variation)")
                                              .Argument <StringGraphType>("filter", "This parameter applies a filter to the query results")
                                              .Argument <StringGraphType>("cultureName", "The language for which all localized property dictionary items will be returned")
                                              .PageSize(20);

            propertiesConnectionBuilder.ResolveAsync(async context =>
            {
                var store = await _storeService.GetByIdAsync(context.GetArgument <string>("storeId"));
                context.UserContext["catalog"] = store.Catalog;

                //PT-1606:  Need to check what there is no any alternative way to access to the original request arguments in sub selection
                context.CopyArgumentsToUserContext();
                return(await ResolvePropertiesConnectionAsync(_mediator, context));
            });

            schema.Query.AddField(propertiesConnectionBuilder.FieldType);

            var propertyField = new FieldType
            {
                Name      = "property",
                Arguments = new QueryArguments(
                    new QueryArgument <NonNullGraphType <StringGraphType> > {
                    Name = "id", Description = "id of the property"
                },
                    new QueryArgument <StringGraphType> {
                    Name = "cultureName", Description = "The language for which all localized property dictionary items will be returned"
                }
                    ),
                Type     = GraphTypeExtenstionHelper.GetActualType <PropertyType>(),
                Resolver = new AsyncFieldResolver <PropertyType, IDataLoaderResult <Property> >(context =>
                {
                    //PT-1606:  Need to check what there is no any alternative way to access to the original request arguments in sub selection
                    context.CopyArgumentsToUserContext();
                    var loader = _dataLoader.Context.GetOrAddBatchLoader <string, Property>("propertiesLoader", (ids) => LoadPropertiesAsync(_mediator, ids));
                    return(Task.FromResult(loader.LoadAsync(context.GetArgument <string>("id"))));
                })
            };

            schema.Query.AddField(propertyField);
        }
Пример #7
0
        public void Build(ISchema schema)
        {
            ValueConverter.Register <ExpOrderAddress, Optional <ExpOrderAddress> >(x => new Optional <ExpOrderAddress>(x));

            _ = schema.Query.AddField(new FieldType
            {
                Name      = "order",
                Arguments = AbstractTypeFactory <OrderQueryArguments> .TryCreateInstance(),
                Type      = GraphTypeExtenstionHelper.GetActualType <CustomerOrderType>(),
                Resolver  = new AsyncFieldResolver <object>(async context =>
                {
                    var request = context.ExtractQuery <GetOrderQuery>();

                    context.CopyArgumentsToUserContext();
                    var orderAggregate = await _mediator.Send(request);

                    var authorizationResult = await _authorizationService.AuthorizeAsync(context.GetCurrentPrincipal(), orderAggregate.Order, new CanAccessOrderAuthorizationRequirement());

                    if (!authorizationResult.Succeeded)
                    {
                        throw new AuthorizationError($"Access denied");
                    }

                    var allCurrencies = await _currencyService.GetAllCurrenciesAsync();
                    //Store all currencies in the user context for future resolve in the schema types
                    context.SetCurrencies(allCurrencies, request.CultureName);

                    //store order aggregate in the user context for future usage in the graph types resolvers
                    context.SetExpandedObjectGraph(orderAggregate);

                    return(orderAggregate);
                })
            });

            var orderConnectionBuilder = GraphTypeExtenstionHelper
                                         .CreateConnection <CustomerOrderType, object>()
                                         .Name("orders")
                                         .PageSize(20)
                                         .Arguments();

            orderConnectionBuilder.ResolveAsync(async context => await ResolveOrdersConnectionAsync(_mediator, context));
            schema.Query.AddField(orderConnectionBuilder.FieldType);

            var paymentsConnectionBuilder = GraphTypeExtenstionHelper
                                            .CreateConnection <PaymentInType, object>()
                                            .Name("payments")
                                            .PageSize(20)
                                            .Arguments();

            paymentsConnectionBuilder.ResolveAsync(async context => await ResolvePaymentsConnectionAsync(_mediator, context));
            schema.Query.AddField(paymentsConnectionBuilder.FieldType);

            _ = schema.Mutation.AddField(FieldBuilder.Create <object, CustomerOrderAggregate>(GraphTypeExtenstionHelper.GetActualType <CustomerOrderType>())
                                         .Name("createOrderFromCart")
                                         .Argument(GraphTypeExtenstionHelper.GetActualComplexType <NonNullGraphType <InputCreateOrderFromCartType> >(), _commandName)
                                         .ResolveAsync(async context =>
            {
                var type     = GenericTypeHelper.GetActualType <CreateOrderFromCartCommand>();
                var response = (CustomerOrderAggregate)await _mediator.Send(context.GetArgument(type, _commandName));
                context.SetExpandedObjectGraph(response);
                return(response);
            })
                                         .FieldType);

            _ = schema.Mutation.AddField(FieldBuilder.Create <object, bool>(typeof(BooleanGraphType))
                                         .Name("changeOrderStatus")
                                         .Argument(GraphTypeExtenstionHelper.GetActualComplexType <NonNullGraphType <InputChangeOrderStatusType> >(), _commandName)
                                         .ResolveAsync(async context =>
            {
                var type    = GenericTypeHelper.GetActualType <ChangeOrderStatusCommand>();
                var command = (ChangeOrderStatusCommand)context.GetArgument(type, _commandName);
                await CheckAuthAsync(context, command.OrderId);

                return(await _mediator.Send(command));
            })
                                         .FieldType);

            _ = schema.Mutation.AddField(FieldBuilder.Create <object, ProcessPaymentRequestResult>(typeof(ProcessPaymentRequestResultType))
                                         .Name("processOrderPayment")
                                         .Argument(GraphTypeExtenstionHelper.GetActualComplexType <NonNullGraphType <InputProcessOrderPaymentType> >(), _commandName)
                                         .ResolveAsync(async context =>
            {
                var type    = GenericTypeHelper.GetActualType <ProcessOrderPaymentCommand>();
                var command = (ProcessOrderPaymentCommand)context.GetArgument(type, _commandName);
                await CheckAuthAsync(context, command.OrderId);

                return(await _mediator.Send(command));
            })
                                         .DeprecationReason("Obsolete. Use 'initializePayment' mutation")
                                         .FieldType);

            _ = schema.Mutation.AddField(FieldBuilder.Create <object, InitializePaymentResult>(typeof(InitializePaymentResultType))
                                         .Name("initializePayment")
                                         .Argument(GraphTypeExtenstionHelper.GetActualComplexType <NonNullGraphType <InputInitializePaymentType> >(), _commandName)
                                         .ResolveAsync(async context =>
            {
                var type = GenericTypeHelper.GetActualType <InitializePaymentCommand>();

                var command = (InitializePaymentCommand)context.GetArgument(type, _commandName);
                await CheckAuthAsync(context, command.OrderId);

                return(await _mediator.Send(command));
            })
                                         .FieldType);

            _ = schema.Mutation.AddField(FieldBuilder.Create <object, AuthorizePaymentResult>(typeof(AuthorizePaymentResultType))
                                         .Name("authorizePayment")
                                         .Argument(GraphTypeExtenstionHelper.GetActualComplexType <NonNullGraphType <InputAuthorizePaymentType> >(), _commandName)
                                         .ResolveAsync(async context =>
            {
                var type = GenericTypeHelper.GetActualType <AuthorizePaymentCommand>();

                var command = (AuthorizePaymentCommand)context.GetArgument(type, _commandName);
                await CheckAuthAsync(context, command.OrderId);

                return(await _mediator.Send(command));
            })
                                         .FieldType);


            _ = schema.Mutation.AddField(FieldBuilder.Create <CustomerOrderAggregate, CustomerOrderAggregate>(GraphTypeExtenstionHelper.GetActualType <CustomerOrderType>())
                                         .Name("updateOrderDynamicProperties")
                                         .Argument(GraphTypeExtenstionHelper.GetActualComplexType <NonNullGraphType <InputUpdateOrderDynamicPropertiesType> >(), _commandName)
                                         .ResolveAsync(async context =>
            {
                var type    = GenericTypeHelper.GetActualType <UpdateOrderDynamicPropertiesCommand>();
                var command = (UpdateOrderDynamicPropertiesCommand)context.GetArgument(type, _commandName);
                await CheckAuthAsync(context, command.OrderId);

                return(await _mediator.Send(command));
            })
                                         .FieldType);

            _ = schema.Mutation.AddField(FieldBuilder.Create <CustomerOrderAggregate, CustomerOrderAggregate>(GraphTypeExtenstionHelper.GetActualType <CustomerOrderType>())
                                         .Name("updateOrderItemDynamicProperties")
                                         .Argument(GraphTypeExtenstionHelper.GetActualComplexType <NonNullGraphType <InputUpdateOrderItemDynamicPropertiesType> >(), _commandName)
                                         .ResolveAsync(async context =>
            {
                var type    = GenericTypeHelper.GetActualType <UpdateOrderItemDynamicPropertiesCommand>();
                var command = (UpdateOrderItemDynamicPropertiesCommand)context.GetArgument(type, _commandName);
                await CheckAuthAsync(context, command.OrderId);

                return(await _mediator.Send(command));
            })
                                         .FieldType);

            _ = schema.Mutation.AddField(FieldBuilder.Create <CustomerOrderAggregate, CustomerOrderAggregate>(GraphTypeExtenstionHelper.GetActualType <CustomerOrderType>())
                                         .Name("updateOrderPaymentDynamicProperties")
                                         .Argument(GraphTypeExtenstionHelper.GetActualComplexType <NonNullGraphType <InputUpdateOrderPaymentDynamicPropertiesType> >(), _commandName)
                                         .ResolveAsync(async context =>
            {
                var type    = GenericTypeHelper.GetActualType <UpdateOrderPaymentDynamicPropertiesCommand>();
                var command = (UpdateOrderPaymentDynamicPropertiesCommand)context.GetArgument(type, _commandName);
                await CheckAuthAsync(context, command.OrderId);

                return(await _mediator.Send(command));
            })
                                         .FieldType);

            _ = schema.Mutation.AddField(FieldBuilder.Create <CustomerOrderAggregate, CustomerOrderAggregate>(GraphTypeExtenstionHelper.GetActualType <CustomerOrderType>())
                                         .Name("updateOrderShipmentDynamicProperties")
                                         .Argument(GraphTypeExtenstionHelper.GetActualComplexType <NonNullGraphType <InputUpdateOrderShipmentDynamicPropertiesType> >(), _commandName)
                                         .ResolveAsync(async context =>
            {
                var type    = GenericTypeHelper.GetActualType <UpdateOrderShipmentDynamicPropertiesCommand>();
                var command = (UpdateOrderShipmentDynamicPropertiesCommand)context.GetArgument(type, _commandName);
                await CheckAuthAsync(context, command.OrderId);

                return(await _mediator.Send(command));
            })
                                         .FieldType);

            _ = schema.Mutation.AddField(FieldBuilder.Create <CustomerOrderAggregate, CustomerOrderAggregate>(GraphTypeExtenstionHelper.GetActualType <CustomerOrderType>())
                                         .Name("addOrUpdateOrderPayment")
                                         .Argument(GraphTypeExtenstionHelper.GetActualComplexType <NonNullGraphType <InputAddOrUpdateOrderPaymentType> >(), _commandName)
                                         .ResolveAsync(async context =>
            {
                var type    = GenericTypeHelper.GetActualType <AddOrUpdateOrderPaymentCommand>();
                var command = (AddOrUpdateOrderPaymentCommand)context.GetArgument(type, _commandName);
                await CheckAuthAsync(context, command.OrderId);

                var response = await _mediator.Send(command);

                context.SetExpandedObjectGraph(response);

                return(response);
            })
                                         .FieldType);
        }
        public void Build(ISchema schema)
        {
            //Queries
            //We can't use the fluent syntax for new types registration provided by dotnet graphql here, because we have the strict requirement for underlying types extensions
            //and must use GraphTypeExtenstionHelper to resolve the effective type on execution time
            var cartField = new FieldType
            {
                Name      = "cart",
                Arguments = new QueryArguments(
                    new QueryArgument <NonNullGraphType <StringGraphType> > {
                    Name = "storeId", Description = "Store Id"
                },
                    new QueryArgument <StringGraphType> {
                    Name = "userId", Description = "User Id"
                },
                    new QueryArgument <NonNullGraphType <StringGraphType> > {
                    Name = "currencyCode", Description = "Currency code (\"USD\")"
                },
                    new QueryArgument <StringGraphType> {
                    Name = "cultureName", Description = "Culture name (\"en-Us\")"
                },
                    new QueryArgument <StringGraphType> {
                    Name = "cartName", Description = "Cart name"
                },
                    new QueryArgument <StringGraphType> {
                    Name = "type", Description = "Cart type"
                }),
                Type     = GraphTypeExtenstionHelper.GetActualType <CartType>(),
                Resolver = new AsyncFieldResolver <object>(async context =>
                {
                    var getCartQuery           = context.GetCartQuery <GetCartQuery>();
                    getCartQuery.IncludeFields = context.SubFields.Values.GetAllNodesPaths().ToArray();
                    context.CopyArgumentsToUserContext();
                    var cartAggregate = await _mediator.Send(getCartQuery);
                    if (cartAggregate == null)
                    {
                        var createCartCommand = new CreateCartCommand(getCartQuery.StoreId, getCartQuery.CartType, getCartQuery.CartName, getCartQuery.UserId, getCartQuery.CurrencyCode, getCartQuery.CultureName);
                        cartAggregate         = await _mediator.Send(createCartCommand);
                    }

                    context.SetExpandedObjectGraph(cartAggregate);

                    return(cartAggregate);
                })
            };

            schema.Query.AddField(cartField);


            var orderConnectionBuilder = GraphTypeExtenstionHelper.CreateConnection <CartType, object>()
                                         .Name("carts")
                                         .Argument <StringGraphType>("storeId", "")
                                         .Argument <StringGraphType>("userId", "")
                                         .Argument <StringGraphType>("currencyCode", "")
                                         .Argument <StringGraphType>("cultureName", "")
                                         .Argument <StringGraphType>("cartType", "")
                                         .Argument <StringGraphType>("filter", "This parameter applies a filter to the query results")
                                         .Argument <StringGraphType>("sort", "The sort expression")
                                         .Unidirectional()
                                         .PageSize(20);

            orderConnectionBuilder.ResolveAsync(async context => await ResolveConnectionAsync(_mediator, context));

            schema.Query.AddField(orderConnectionBuilder.FieldType);

            //Mutations
            /// <example>
            /// This is an example JSON request for a mutation
            /// {
            ///   "query": "mutation ($command:InputAddItemType!){ addItem(command: $command) {  total { formatedAmount } } }",
            ///   "variables": {
            ///      "command": {
            ///          "storeId": "Electronics",
            ///          "cartName": "default",
            ///          "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa",
            ///          "language": "en-US",
            ///          "currency": "USD",
            ///          "cartType": "cart",
            ///          "productId": "9cbd8f316e254a679ba34a900fccb076",
            ///          "quantity": 1
            ///      }
            ///   }
            /// }
            /// </example>
            var addItemField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType))
                               .Name("addItem")
                               .Argument <NonNullGraphType <InputAddItemType> >(_commandName)
                               //TODO: Write the unit-tests for successfully mapping input variable to the command
                               .ResolveAsync(async context =>
            {
                //TODO: Need to refactor later to prevent ugly code duplication
                //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency)
                var cartAggregate = await _mediator.Send(context.GetCartCommand <AddCartItemCommand>());
                //store cart aggregate in the user context for future usage in the graph types resolvers
                context.SetExpandedObjectGraph(cartAggregate);
                return(cartAggregate);
            })
                               .FieldType;

            schema.Mutation.AddField(addItemField);

            /// <example>
            /// This is an example JSON request for a mutation
            /// {
            ///   "query": "mutation ($command:InputClearCartType!){ clearCart(command: $command) {  total { formatedAmount } } }",
            ///   "variables": {
            ///      "command": {
            ///          "storeId": "Electronics",
            ///          "cartName": "default",
            ///          "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa",
            ///          "language": "en-US",
            ///          "currency": "USD",
            ///          "cartType": "cart"
            ///      }
            ///   }
            /// }
            /// </example>
            var clearCartField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType))
                                 .Name("clearCart")
                                 .Argument <NonNullGraphType <InputClearCartType> >(_commandName)
                                 .ResolveAsync(async context =>
            {
                //TODO: Need to refactor later to prevent ugly code duplication
                //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency)
                var cartAggregate = await _mediator.Send(context.GetCartCommand <ClearCartCommand>());
                //store cart aggregate in the user context for future usage in the graph types resolvers
                context.SetExpandedObjectGraph(cartAggregate);
                return(cartAggregate);
            }).FieldType;

            schema.Mutation.AddField(clearCartField);

            /// <example>
            /// This is an example JSON request for a mutation
            /// {
            ///   "query": "mutation ($command:InputChangeCommentType!){ changeComment(command: $command) {  total { formatedAmount } } }",
            ///   "variables": {
            ///      "command": {
            ///          "storeId": "Electronics",
            ///          "cartName": "default",
            ///          "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa",
            ///          "language": "en-US",
            ///          "currency": "USD",
            ///          "cartType": "cart",
            ///          "comment": "Hi, Virto!"
            ///      }
            ///   }
            /// }
            /// </example>
            var changeCommentField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType))
                                     .Name("changeComment")
                                     .Argument <InputChangeCommentType>(_commandName)
                                     .ResolveAsync(async context =>
            {
                //TODO: Need to refactor later to prevent ugly code duplication
                //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency)
                var cartAggregate = await _mediator.Send(context.GetCartCommand <ChangeCommentCommand>());
                //store cart aggregate in the user context for future usage in the graph types resolvers
                context.SetExpandedObjectGraph(cartAggregate);
                return(cartAggregate);
            })
                                     .FieldType;

            schema.Mutation.AddField(changeCommentField);

            /// <example>
            /// This is an example JSON request for a mutation
            /// {
            ///   "query": "mutation ($command:InputChangeCartItemPriceType!){ changeCartItemPrice(command: $command) {  total { formatedAmount } } }",
            ///   "variables": {
            ///      "command": {
            ///          "storeId": "Electronics",
            ///          "cartName": "default",
            ///          "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa",
            ///          "language": "en-US",
            ///          "currency": "USD",
            ///          "cartType": "cart",
            ///          "lineItemId": "9cbd8f316e254a679ba34a900fccb076",
            ///          "price": 777
            ///      }
            ///   }
            /// }
            /// </example>
            var changeCartItemPriceField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType))
                                           .Name("changeCartItemPrice")
                                           .Argument <NonNullGraphType <InputChangeCartItemPriceType> >(_commandName)
                                           .ResolveAsync(async context =>
            {
                //TODO: Need to refactor later to prevent ugly code duplication
                //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency)
                var cartAggregate = await _mediator.Send(context.GetCartCommand <ChangeCartItemPriceCommand>());
                //store cart aggregate in the user context for future usage in the graph types resolvers
                context.SetExpandedObjectGraph(cartAggregate);
                return(cartAggregate);
            }).FieldType;

            schema.Mutation.AddField(changeCartItemPriceField);

            /// <example>
            /// This is an example JSON request for a mutation
            /// {
            ///   "query": "mutation ($command:InputChangeCartItemQuantityType!){ changeCartItemQuantity(command: $command) {  total { formatedAmount } } }",
            ///   "variables": {
            ///      "command": {
            ///          "storeId": "Electronics",
            ///          "cartName": "default",
            ///          "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa",
            ///          "language": "en-US",
            ///          "currency": "USD",
            ///          "cartType": "cart",
            ///          "lineItemId": "9cbd8f316e254a679ba34a900fccb076",
            ///          "quantity": 777
            ///      }
            ///   }
            /// }
            /// </example>
            var changeCartItemQuantityField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType))
                                              .Name("changeCartItemQuantity")
                                              .Argument <NonNullGraphType <InputChangeCartItemQuantityType> >(_commandName)
                                              .ResolveAsync(async context =>
            {
                //TODO: Need to refactor later to prevent ugly code duplication
                //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency)
                var cartAggregate = await _mediator.Send(context.GetCartCommand <ChangeCartItemQuantityCommand>());
                //store cart aggregate in the user context for future usage in the graph types resolvers
                context.SetExpandedObjectGraph(cartAggregate);
                return(cartAggregate);
            }).FieldType;

            schema.Mutation.AddField(changeCartItemQuantityField);

            /// <example>
            /// This is an example JSON request for a mutation
            /// {
            ///   "query": "mutation ($command:InputChangeCartItemCommentType!){ changeCartItemComment(command: $command) {  total { formatedAmount } } }",
            ///   "variables": {
            ///      "command": {
            ///          "storeId": "Electronics",
            ///          "cartName": "default",
            ///          "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa",
            ///          "language": "en-US",
            ///          "currency": "USD",
            ///          "cartType": "cart",
            ///          "lineItemId": "9cbd8f316e254a679ba34a900fccb076",
            ///          "comment": "verynicecomment"
            ///      }
            ///   }
            /// }
            /// </example>
            var changeCartItemCommentField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType))
                                             .Name("changeCartItemComment")
                                             .Argument <InputChangeCartItemCommentType>(_commandName)
                                             .ResolveAsync(async context =>
            {
                //TODO: Need to refactor later to prevent ugly code duplication
                //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency)
                var cartAggregate = await _mediator.Send(context.GetCartCommand <ChangeCartItemCommentCommand>());
                //store cart aggregate in the user context for future usage in the graph types resolvers
                context.SetExpandedObjectGraph(cartAggregate);
                return(cartAggregate);
            }).FieldType;

            schema.Mutation.AddField(changeCartItemCommentField);

            /// <example>
            /// This is an example JSON request for a mutation
            /// {
            ///   "query": "mutation ($command:InputRemoveItemType!){ removeCartItem(command: $command) {  total { formatedAmount } } }",
            ///   "variables": {
            ///      "command": {
            ///          "storeId": "Electronics",
            ///          "cartName": "default",
            ///          "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa",
            ///          "language": "en-US",
            ///          "currency": "USD",
            ///          "cartType": "cart",
            ///          "lineItemId": "9cbd8f316e254a679ba34a900fccb076"
            ///      }
            ///   }
            /// }
            /// </example>
            var removeCartItemField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType))
                                      .Name("removeCartItem")
                                      .Argument <NonNullGraphType <InputRemoveItemType> >(_commandName)
                                      .ResolveAsync(async context =>
            {
                //TODO: Need to refactor later to prevent ugly code duplication
                //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency)
                var cartAggregate = await _mediator.Send(context.GetCartCommand <RemoveCartItemCommand>());
                //store cart aggregate in the user context for future usage in the graph types resolvers
                context.SetExpandedObjectGraph(cartAggregate);
                return(cartAggregate);
            }).FieldType;

            schema.Mutation.AddField(removeCartItemField);

            /// <example>
            /// This is an example JSON request for a mutation
            /// {
            ///   "query": "mutation ($command:InputAddCouponType!){ addCoupon(command: $command) {  total { formatedAmount } } }",
            ///   "variables": {
            ///      "command": {
            ///          "storeId": "Electronics",
            ///          "cartName": "default",
            ///          "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa",
            ///          "language": "en-US",
            ///          "currency": "USD",
            ///          "cartType": "cart",
            ///          "couponCode": "verynicecouponcode"
            ///      }
            ///   }
            /// }
            /// </example>
            var addCouponField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType))
                                 .Name("addCoupon")
                                 .Argument <NonNullGraphType <InputAddCouponType> >(_commandName)
                                 .ResolveAsync(async context =>
            {
                //TODO: Need to refactor later to prevent ugly code duplication
                //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency)
                var cartAggregate = await _mediator.Send(context.GetCartCommand <AddCouponCommand>());
                //store cart aggregate in the user context for future usage in the graph types resolvers
                context.SetExpandedObjectGraph(cartAggregate);
                return(cartAggregate);
            }).FieldType;

            schema.Mutation.AddField(addCouponField);

            /// <example>
            /// This is an example JSON request for a mutation
            /// {
            ///   "query": "mutation ($command:InputRemoveCouponType!){ removeCoupon(command: $command) {  total { formatedAmount } } }",
            ///   "variables": {
            ///      "command": {
            ///          "storeId": "Electronics",
            ///          "cartName": "default",
            ///          "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa",
            ///          "language": "en-US",
            ///          "currency": "USD",
            ///          "cartType": "cart",
            ///          "couponCode": "verynicecouponcode"
            ///      }
            ///   }
            /// }
            /// </example>
            var removeCouponField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType))
                                    .Name("removeCoupon")
                                    .Argument <NonNullGraphType <InputRemoveCouponType> >(_commandName)
                                    .ResolveAsync(async context =>
            {
                //TODO: Need to refactor later to prevent ugly code duplication
                //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency)
                var cartAggregate = await _mediator.Send(context.GetCartCommand <RemoveCouponCommand>());
                //store cart aggregate in the user context for future usage in the graph types resolvers
                context.SetExpandedObjectGraph(cartAggregate);
                return(cartAggregate);
            }).FieldType;

            schema.Mutation.AddField(removeCouponField);

            /// <example>
            /// This is an example JSON request for a mutation
            /// {
            ///   "query": "mutation ($command:InputRemoveShipmentType!){ removeShipment(command: $command) {  total { formatedAmount } } }",
            ///   "variables": {
            ///      "command": {
            ///          "storeId": "Electronics",
            ///          "cartName": "default",
            ///          "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa",
            ///          "language": "en-US",
            ///          "currency": "USD",
            ///          "cartType": "cart",
            ///          "shipmentId": "7777-7777-7777-7777"
            ///      }
            ///   }
            /// }
            /// </example>
            var removeShipmentField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType))
                                      .Name("removeShipment")
                                      .Argument <NonNullGraphType <InputRemoveShipmentType> >(_commandName)
                                      .ResolveAsync(async context =>
            {
                //TODO: Need to refactor later to prevent ugly code duplication
                //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency)
                var cartAggregate = await _mediator.Send(context.GetCartCommand <RemoveShipmentCommand>());
                //store cart aggregate in the user context for future usage in the graph types resolvers
                context.SetExpandedObjectGraph(cartAggregate);
                return(cartAggregate);
            }).FieldType;

            schema.Mutation.AddField(removeShipmentField);

            //TODO: add shipment model to example
            /// <example>
            /// This is an example JSON request for a mutation
            /// {
            ///   "query": "mutation ($command:InputAddOrUpdateCartShipmentType!){ addOrUpdateCartShipment(command: $command) {  total { formatedAmount } } }",
            ///   "variables": {
            ///      "command": {
            ///          "storeId": "Electronics",
            ///          "cartName": "default",
            ///          "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa",
            ///          "language": "en-US",
            ///          "currency": "USD",
            ///          "cartType": "cart",
            ///          "shipment": { }
            ///      }
            ///   }
            /// }
            /// </example>
            var addOrUpdateCartShipmentField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType))
                                               .Name("addOrUpdateCartShipment")
                                               .Argument <NonNullGraphType <InputAddOrUpdateCartShipmentType> >(_commandName)
                                               .ResolveAsync(async context =>
            {
                //TODO: Need to refactor later to prevent ugly code duplication
                //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency)
                var cartAggregate = await _mediator.Send(context.GetCartCommand <AddOrUpdateCartShipmentCommand>());
                //store cart aggregate in the user context for future usage in the graph types resolvers
                context.SetExpandedObjectGraph(cartAggregate);
                return(cartAggregate);
            }).FieldType;

            schema.Mutation.AddField(addOrUpdateCartShipmentField);

            //TODO: add payment model to example
            /// <example>
            /// This is an example JSON request for a mutation
            /// {
            ///   "query": "mutation ($command:InputAddOrUpdateCartPaymentType!){ addOrUpdateCartPayment(command: $command) {  total { formatedAmount } } }",
            ///   "variables": {
            ///      "command": {
            ///          "storeId": "Electronics",
            ///          "cartName": "default",
            ///          "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa",
            ///          "language": "en-US",
            ///          "currency": "USD",
            ///          "cartType": "cart",
            ///          "payment": { }
            ///      }
            ///   }
            /// }
            /// </example>
            var addOrUpdateCartPaymentField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType))
                                              .Name("addOrUpdateCartPayment")
                                              .Argument <NonNullGraphType <InputAddOrUpdateCartPaymentType> >(_commandName)
                                              .ResolveAsync(async context =>
            {
                //TODO: Need to refactor later to prevent ugly code duplication
                //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency)
                var cartAggregate = await _mediator.Send(context.GetCartCommand <AddOrUpdateCartPaymentCommand>());
                //store cart aggregate in the user context for future usage in the graph types resolvers
                context.SetExpandedObjectGraph(cartAggregate);
                return(cartAggregate);
            }).FieldType;

            schema.Mutation.AddField(addOrUpdateCartPaymentField);

            /// <example>
            /// This is an example JSON request for a mutation
            /// {
            ///   "query": "mutation ($command:InputValidateCouponType!){ validateCoupon(command: $command) }",
            ///   "variables": {
            ///      "command": {
            ///          "storeId": "Electronics",
            ///          "cartName": "default",
            ///          "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa",
            ///          "language": "en-US",
            ///          "currency": "USD",
            ///          "cartType": "cart",
            ///          "coupon": {
            ///             "code":"verynicecodeforvalidation"
            ///         }
            ///      }
            ///   }
            /// }
            /// </example>
            var validateCouponField = FieldBuilder.Create <CartAggregate, bool>(typeof(BooleanGraphType))
                                      .Name("validateCoupon")
                                      .Argument <NonNullGraphType <InputValidateCouponType> >(_commandName)
                                      .ResolveAsync(async context => await _mediator.Send(context.GetArgument <ValidateCouponCommand>(_commandName)))
                                      .FieldType;

            schema.Mutation.AddField(validateCouponField);

            /// <example>
            /// This is an example JSON request for a mutation
            /// {
            ///   "query": "mutation ($command:MergeCartType!){ mergeCart(command: $command) {  total { formatedAmount } } }",
            ///   "variables": {
            ///      "command": {
            ///          "storeId": "Electronics",
            ///          "cartName": "default",
            ///          "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa",
            ///          "language": "en-US",
            ///          "currency": "USD",
            ///          "cartType": "cart",
            ///          "secondCartId": "7777-7777-7777-7777"
            ///      }
            ///   }
            /// }
            /// </example>
            var margeCartField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType))
                                 .Name("mergeCart")
                                 .Argument <NonNullGraphType <InputMergeCartType> >(_commandName)
                                 .ResolveAsync(async context =>
            {
                //TODO: Need to refactor later to prevent ugly code duplication
                //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency)
                var cartAggregate = await _mediator.Send(context.GetCartCommand <MergeCartCommand>());
                //store cart aggregate in the user context for future usage in the graph types resolvers
                context.SetExpandedObjectGraph(cartAggregate);
                return(cartAggregate);
            }).FieldType;

            schema.Mutation.AddField(margeCartField);

            /// <example>
            /// This is an example JSON request for a mutation
            /// {
            ///   "query": "mutation ($command:InputRemoveCartType!){ removeCart(command: $command) {  total { formatedAmount } } }",
            ///   "variables": {
            ///      "command": {
            ///          "cartId": "7777-7777-7777-7777"
            ///      }
            ///   }
            /// }
            /// </example>
            var removeCartField = FieldBuilder.Create <CartAggregate, bool>(typeof(BooleanGraphType))
                                  .Name("removeCart")
                                  .Argument <NonNullGraphType <InputRemoveCartType> >(_commandName)
                                  .ResolveAsync(async context => await _mediator.Send(context.GetArgument <RemoveCartCommand>(_commandName)))
                                  .FieldType;

            schema.Mutation.AddField(removeCartField);

            /// <example>
            /// This is an example JSON request for a mutation
            /// {
            ///   "query": "mutation ($command:InputClearShipmentsType!){ clearShipments(command: $command) {  total { formatedAmount } } }",
            ///   "variables": {
            ///      "command": {
            ///          "cartId": "7777-7777-7777-7777"
            ///      }
            ///   }
            /// }
            /// </example>
            var clearShipmentsField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType))
                                      .Name("clearShipments")
                                      .Argument <NonNullGraphType <InputClearShipmentsType> >(_commandName)
                                      .ResolveAsync(async context =>
            {
                //TODO: Need to refactor later to prevent ugly code duplication
                //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency)
                var cartAggregate = await _mediator.Send(context.GetArgument <ClearShipmentsCommand>(_commandName));
                //store cart aggregate in the user context for future usage in the graph types resolvers
                context.SetExpandedObjectGraph(cartAggregate);
                return(cartAggregate);
            })
                                      .FieldType;

            schema.Mutation.AddField(clearShipmentsField);

            /// <example>
            /// This is an example JSON request for a mutation
            /// {
            ///   "query": "mutation ($command:InputClearPaymentsType!){ clearPayments(command: $command) {  total { formatedAmount } } }",
            ///   "variables": {
            ///      "command": {
            ///          "cartId": "7777-7777-7777-7777"
            ///      }
            ///   }
            /// }
            /// </example>
            var clearPaymentsField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType))
                                     .Name("clearPayments")
                                     .Argument <NonNullGraphType <InputClearPaymentsType> >(_commandName)
                                     .ResolveAsync(async context =>
            {
                //TODO: Need to refactor later to prevent ugly code duplication
                //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency)
                var cartAggregate = await _mediator.Send(context.GetArgument <ClearPaymentsCommand>(_commandName));
                //store cart aggregate in the user context for future usage in the graph types resolvers
                context.SetExpandedObjectGraph(cartAggregate);
                return(cartAggregate);
            })
                                     .FieldType;

            schema.Mutation.AddField(clearPaymentsField);


            /// <example>
            /// This is an example JSON request for a mutation
            /// {
            ///   "query": "mutation ($command:InputAddOrUpdateCartAddressType!){ addOrUpdateCartAddress(command: $command) {  total { formatedAmount } } }",
            ///   "variables": {
            ///      "command": {
            ///          "storeId": "Electronics",
            ///          "cartName": "default",
            ///          "userId": "b57d06db-1638-4d37-9734-fd01a9bc59aa",
            ///          "language": "en-US",
            ///          "currency": "USD",
            ///          "cartType": "cart",
            ///          "address": {
            ///             "line1":"st street 1"
            ///         }
            ///      }
            ///   }
            /// }
            /// </example>
            var addOrUpdateCartAddress = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType))
                                         .Name("addOrUpdateCartAddress")
                                         .Argument <NonNullGraphType <InputAddOrUpdateCartAddressType> >(_commandName)
                                         .ResolveAsync(async context =>
            {
                //TODO: Need to refactor later to prevent ugly code duplication
                //We need to add cartAggregate to the context to be able use it on nested cart types resolvers (e.g for currency)
                var cartAggregate = await _mediator.Send(context.GetArgument <AddOrUpdateCartAddressCommand>(_commandName));
                //store cart aggregate in the user context for future usage in the graph types resolvers
                context.SetExpandedObjectGraph(cartAggregate);
                return(cartAggregate);
            })
                                         .FieldType;

            schema.Mutation.AddField(addOrUpdateCartAddress);

            /// <example>
            /// This is an example JSON request for a mutation
            /// {
            ///   "query": "mutation ($command:InputRemoveCartAddressType!){ removeCartAddress(command: $command) {  total { formatedAmount } } }",
            ///   "variables": {
            ///      "command": {
            ///          "cartId": "7777-7777-7777-7777",
            ///          "addressId": "111"
            ///      }
            ///   }
            /// }
            /// </example>
            var removeCartAddressField = FieldBuilder.Create <CartAggregate, CartAggregate>(typeof(CartType))
                                         .Name("removeCartAddress")
                                         .Argument <NonNullGraphType <InputRemoveCartAddressType> >(_commandName)
                                         .ResolveAsync(async context => await _mediator.Send(context.GetArgument <RemoveCartAddressCommand>(_commandName)))
                                         .FieldType;

            schema.Mutation.AddField(removeCartAddressField);
        }
Пример #9
0
        public void Build(ISchema schema)
        {
            _ = schema.Query.AddField(new FieldType
            {
                Name      = "order",
                Arguments = new QueryArguments(
                    new QueryArgument <StringGraphType> {
                    Name = "id"
                },
                    new QueryArgument <StringGraphType> {
                    Name = "number"
                },
                    new QueryArgument <StringGraphType> {
                    Name = "cultureName", Description = "Culture name (\"en-US\")"
                }),
                Type     = GraphTypeExtenstionHelper.GetActualType <CustomerOrderType>(),
                Resolver = new AsyncFieldResolver <object>(async context =>
                {
                    var request = new GetOrderQuery
                    {
                        Number      = context.GetArgument <string>("number"),
                        OrderId     = context.GetArgument <string>("id"),
                        CultureName = context.GetArgument <string>(nameof(Currency.CultureName))
                    };

                    var orderAggregate = await _mediator.Send(request);

                    var authorizationResult = await _authorizationService.AuthorizeAsync(context.GetCurrentPrincipal(), orderAggregate.Order, new CanAccessOrderAuthorizationRequirement());

                    if (!authorizationResult.Succeeded)
                    {
                        throw new ExecutionError($"Access denied");
                    }

                    var allCurrencies = await _currencyService.GetAllCurrenciesAsync();
                    //Store all currencies in the user context for future resolve in the schema types
                    context.SetCurrencies(allCurrencies, request.CultureName);

                    //store order aggregate in the user context for future usage in the graph types resolvers
                    context.SetExpandedObjectGraph(orderAggregate);

                    return(orderAggregate);
                })
            });

            var orderConnectionBuilder = GraphTypeExtenstionHelper.CreateConnection <CustomerOrderType, object>()
                                         .Name("orders")
                                         .Argument <StringGraphType>("filter", "This parameter applies a filter to the query results")
                                         .Argument <StringGraphType>("sort", "The sort expression")
                                         .Argument <StringGraphType>("cultureName", "Culture name (\"en-US\")")
                                         .Argument <StringGraphType>("userId", "")
                                         .Unidirectional()
                                         .PageSize(20);

            orderConnectionBuilder.ResolveAsync(async context => await ResolveOrdersConnectionAsync(_mediator, context));

            schema.Query.AddField(orderConnectionBuilder.FieldType);


            var paymentsConnectionBuilder = GraphTypeExtenstionHelper.CreateConnection <PaymentInType, object>()
                                            .Name("payments")
                                            .Argument <StringGraphType>("filter", "This parameter applies a filter to the query results")
                                            .Argument <StringGraphType>("sort", "The sort expression")
                                            .Argument <StringGraphType>("cultureName", "Culture name (\"en-US\")")
                                            .Argument <NonNullGraphType <StringGraphType> >("userId", "")
                                            .Unidirectional()
                                            .PageSize(20);

            paymentsConnectionBuilder.ResolveAsync(async context => await ResolvePaymentsConnectionAsync(_mediator, context));
            schema.Query.AddField(paymentsConnectionBuilder.FieldType);


            _ = schema.Mutation.AddField(FieldBuilder.Create <object, CustomerOrderAggregate>(typeof(CustomerOrderType))
                                         .Name("createOrderFromCart")
                                         .Argument <NonNullGraphType <InputCreateOrderFromCartType> >(_commandName)
                                         .ResolveAsync(async context =>
            {
                var response = await _mediator.Send(context.GetArgument <CreateOrderFromCartCommand>(_commandName));
                context.SetExpandedObjectGraph(response);
                return(response);
            })
                                         .FieldType);

            _ = schema.Mutation.AddField(FieldBuilder.Create <object, bool>(typeof(BooleanGraphType))
                                         .Name("changeOrderStatus")
                                         .Argument <NonNullGraphType <InputChangeOrderStatusType> >(_commandName)
                                         .ResolveAsync(async context =>
            {
                var command = context.GetArgument <ChangeOrderStatusCommand>(_commandName);

                var order = await _customerOrderService.GetByIdAsync(command.OrderId);

                var authorizationResult = await _authorizationService.AuthorizeAsync(context.GetCurrentPrincipal(), order, new CanAccessOrderAuthorizationRequirement());

                if (!authorizationResult.Succeeded)
                {
                    throw new ExecutionError($"Access denied");
                }

                return(await _mediator.Send(command));
            })
                                         .FieldType);

            _ = schema.Mutation.AddField(FieldBuilder.Create <object, bool>(typeof(BooleanGraphType))
                                         .Name("confirmOrderPayment")
                                         .Argument <NonNullGraphType <InputConfirmOrderPaymentType> >(_commandName)
                                         .ResolveAsync(async context =>
            {
                var command = context.GetArgument <ConfirmOrderPaymentCommand>(_commandName);
                var order   = await _customerOrderService.GetByIdAsync(command.Payment.OrderId);

                var authorizationResult = await _authorizationService.AuthorizeAsync(context.GetCurrentPrincipal(), order, new CanAccessOrderAuthorizationRequirement());

                if (!authorizationResult.Succeeded)
                {
                    throw new ExecutionError($"Access denied");
                }

                return(await _mediator.Send(command));
            })
                                         .FieldType);

            _ = schema.Mutation.AddField(FieldBuilder.Create <object, bool>(typeof(BooleanGraphType))
                                         .Name("cancelOrderPayment")
                                         .Argument <NonNullGraphType <InputCancelOrderPaymentType> >(_commandName)
                                         .ResolveAsync(async context =>
            {
                var command = context.GetArgument <CancelOrderPaymentCommand>(_commandName);
                var order   = await _customerOrderService.GetByIdAsync(command.Payment.OrderId);

                var authorizationResult = await _authorizationService.AuthorizeAsync(context.GetCurrentPrincipal(), order, new CanAccessOrderAuthorizationRequirement());

                if (!authorizationResult.Succeeded)
                {
                    throw new ExecutionError($"Access denied");
                }

                return(await _mediator.Send(command));
            })
                                         .FieldType);
        }