1

Hi im working of a text book called: Microservices in dotnet book second edition, and have reached a part in chapter where the author talks about Dependency Injection (DI) using a package called Scrutor. However, examples of the book are done in .Net 5 (netcoreapp3.0) and I've been working with .Net 6 which does not have a StartUp file but rather has a Program File as the main file, when a project is generated.

so in the author's code for DI there is the following in StartUp.cs

...
public void ConfigureServices(IServiceCollection services)
{
  services.AddControllers();
  services.Scan(selector =>
  selector
        .FromAssembly<StartUp>()
        .AddClasses()
        .AsImplementedInterfaces());
}
...

And my .net 6 code is as follows in my Program.cs file

...
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.Scan(scan =>
    scan.FromAssemblyOf<Program>()
    .AddClasses()
    .AsImplementedInterfaces());
...

With my controller code implementation:

namespace ShoppingCartMicroservice.ShoppingCart
{
    using Microsoft.AspNetCore.Mvc;
    [ApiController]
    [Route("/shoppingcart")]
    public class ShoppingCartController : ControllerBase
    {
        private readonly IShoppingCartStore shoppingCartStore;

        public ShoppingCartController(IShoppingCartStore shoppingCartStore)
        {
            this.shoppingCartStore = shoppingCartStore;
        }

        [HttpGet("{userId:int}")]
        public ShoppingCart Get(int userId) =>
            this.shoppingCartStore.Get(userId);

    }
}

The interface:

using ShoppingCartMicroservice.ShoppingCart;

public interface IShoppingCartStore
{
    ShoppingCart Get(int userId);
    void save(ShoppingCart shoppingCart);
}

My In memory Shopping car store:

using ShoppingCartMicroservice.ShoppingCart;

public class ShoppingCartStore : IShoppingCartStore
{
    private static readonly Dictionary<int, ShoppingCart> Database = new Dictionary<int, ShoppingCart>();
    public ShoppingCart Get(int userId) =>
    Database.ContainsKey(userId) ? Database[userId] : new ShoppingCart(userId);

    public void save(ShoppingCart shoppingCart) => 
    Database[shoppingCart.UserId] = shoppingCart;
}

And my logic

namespace ShoppingCartMicroservice.ShoppingCart
{
    using System.Collections.Generic;
    using System.Linq;

    public class ShoppingCart
    {
        private readonly HashSet<ShoppingCartItem> items = new();
        public int UserId { get; }
        public IEnumerable<ShoppingCartItem> Items => this.items;
        public ShoppingCart(int UserId) => this.UserId = UserId;

        public void AddItems(IEnumerable<ShoppingCartItem> shoppingCartItems)
        {
            foreach (var item in shoppingCartItems)
            {
                this.items.Add(item);
            }
        }

        public void RemoveItems(int[] productCatalogueIds) =>
            this.items.RemoveWhere(i => productCatalogueIds.Contains(i.ProductCatalogueId));


    }

    public record ShoppingCartItem
    (
    int ProductCatalogueId,
    string ProductName,
    string Description,
    Money Price
    )
    {
        public virtual bool Equals(ShoppingCartItem? obj) =>
        obj != null && this.ProductCatalogueId.Equals(obj.ProductCatalogueId);

        public override int GetHashCode() =>
        this.ProductCatalogueId.GetHashCode();
    }

    public record Money(string Currency, decimal Amount);
}

However with my implementation, at run time I get the following error:

Exception has occurred: CLR/System.AggregateException
An unhandled exception of type 'System.AggregateException' occurred in Microsoft.Extensions.DependencyInjection.dll: 'Some services are not able to be constructed'
 Inner exceptions found, see $exception in variables window for more details.
 Innermost exception     System.InvalidOperationException : Unable to resolve service for type 'System.Int32' while attempting to activate 'ShoppingCartMicroservice.ShoppingCart.ShoppingCartItem'.
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type implementationType, CallSiteChain callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(ResultCache lifetime, Type serviceType, Type implementationType, CallSiteChain callSiteChain)

Link to project: https://github.com/dot-net-microservices-in-action/chapter-02

  • Looks like it's trying to create an instance of ShoppingCartItem but the constructor requires an int. Why is it trying to create an instance of ShoppingCartItem? What class do you have registered that implements IShoppingCartStore, and what are its dependencies? Make sure you provide us a true [mcve], as you've left out crucial details. And make sure you include the full exception details, not just the outermost and innermost exceptions, but all of the exceptions that are contained within the outermost exception. – mason Jun 01 '22 at 19:53

0 Answers0