Search code examples
c#.netmigration

.Net migration not working when I register my repository as a service in Program.cs


So working on an ecommerce application I created my repository interface, class & model.

Then I registered the repository as a service when I added the migration I go this error:

An error occurred while accessing the Microsoft.Extensions.Hosting services. Continuing without the application service provider.

Error: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: CoffeeShop.Models.Interfaces.IOrderRepository Lifetime: Scoped ImplementationType: CoffeeShop.Models.Services.OrderRepository': Unable to resolve service for type 'CoffeeShop.Models.Services.ShoppingCartRepository' while attempting to activate 'CoffeeShop.Models.Services.OrderRepository'.)

Unable to create a 'DbContext' of type ''. The exception 'Unable to resolve service for type 'Microsoft.EntityFrameworkCore.DbContextOptions`1[CoffeeShop.Data.CoffeeShopDBContext]' while attempting to activate 'CoffeeShop.Data.CoffeeShopDBContext'.' was thrown while attempting to create an instance. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728

My other repositories like shopping cart have been working fine. But when I remove the registration in Program.cs I don't get any errors:

builder.Services.AddControllersWithViews();

builder.Services.AddScoped<IProductRepository, ProductRepository>();

//  This line of code below is causing the issue 
builder.Services.AddScoped<IOrderRepository, OrderRepository>();

builder.Services.AddDbContext<CoffeeShopDBContext>(option => option.UseSqlServer(builder.Configuration.GetConnectionString("CoffeeShopDbConnection")));
builder.Services.AddScoped<IShoppingCartRepository, ShoppingCartRepository>(s => ShoppingCartRepository.GetCart(s));

I've doubled checked that all the required services have been registered and the repository and models are configured correctly.

Here is my repository class:

using CoffeeShop.Data;
using CoffeeShop.Models.Interfaces;

namespace CoffeeShop.Models.Services
{
    public class OrderRepository : IOrderRepository
    {
        private CoffeeShopDBContext dBContext;
        private IShoppingCartRepository shopCartRepository;

        public OrderRepository(CoffeeShopDBContext dBContext, ShoppingCartRepository shoppingCartRepository)
        {
            this.dBContext = dBContext; 
            this.shopCartRepository = shoppingCartRepository;   
        }

        public void PlaceOrder(Order order)
        {
           var shoppingCartItems = shopCartRepository.GetShoppingCartItems();
            order.OrderDetails = new List<OrderDetail>(); 

            foreach(var item in shoppingCartItems) 
            {
                var orderDetail = new OrderDetail()
                {
                    Quantity = item.Qty,
                    ProductId = (int)item.Product.Id, 
                    Price = (decimal)item.Product.Price, 
                };

                order.OrderDetails.Add(orderDetail);
            }

            order.OrderPlaced = DateTime.Now;
            order.OrderTotal = shopCartRepository.GetShoppingCartTotal();   

            dBContext.Orders.Add(order);
            dBContext.SaveChanges();    
        }
    }
}

I'm new to .NET so any patience and help would be much appreciated


Solution

  • I believe one issue might be that you're registering an interface but the ctor wants the concrete implementation, which it can't resolve.

    Try to change the ctor from:

    public OrderRepository(CoffeeShopDBContext dBContext, ShoppingCartRepository shoppingCartRepository)
    

    To:

    public OrderRepository(CoffeeShopDBContext dBContext, IShoppingCartRepository shoppingCartRepository)
    

    For the AddDbContext, try changing this:

    builder.Services.AddDbContext<CoffeeShopDBContext>(option => option.UseSqlServer(builder.Configuration.GetConnectionString("CoffeeShopDbConnection")));
    

    To this:

    builder.Services.AddDbContext<CoffeeShopDBContext>(option => option.UseSqlServer("name=ConnectionStrings:CoffeeShopDbConnection"));
    

    The reason is that you can't use builder.Configuration until after .Build() has been called.