I am building an e-commerce site using C #, MVC3, Entity Framework 4, my first hit in MVC3 and Entity Framework, so I want to provide a sound architecture. In particular, I ask a question about my use of interfaces and dependency inversion, as they relate to service and repository tiers. I will focus on one area of the system, the Cart system, for brevity and clarity.
Here, the PluralSite interface inversion example is used to explain a typical trend for creating interfaces without taking into account the corresponding dependencies.
Suppose you have an IKangaroo interface, on which the BoxingMatch class depends. When you add more “boxers,” such as IMikeTyson and IJoeBoxer, you now have three different interfaces, one for each boxer you need to know about “BoxingMatch”. IKangaroo, IMikeTyson, and IJoeBoxer have only one specific implementation, which means you don’t even need these interfaces (you can also make BoxingMatch directly dependent on specific Kangaroo, MikeTyson, and JoeBoxer classes). Also, it doesn't even make sense that there would be more than one implementation of IKangaroo or IMikeTyson. Thus, interfaces are useless and do not add any value to the architecture.
Inverting the dependencies in this example will cause BoxingMatch to define the interface that the classes it intends to use (Kangaroo, MikeTyson, and JoeBoxer). Thus, “BoxingMatch” will depend on the IBoxer interface, and Kangaroo, MikeTyson and JoeBoxer will implement IBoxer. There is an inversion, and that makes sense.
Now my situation ... The CartController constructor has two dependency parameters entered, ICartService and IProductService). CartService takes one argument of the constructor constructor (ICartRepository). CartController calls AddItem () on the CartService, and CartService calls AddItem () on the CartRepository.
ICartRepository has two implementations: CartRepository (in the main web project) and TestCartRepository (in the Tests project). ICartService has only one implementation.
My questions are: how does my architecture stack up before the lesson in the above example? I really don’t see how my CartController may be less connected than it is with CartService. The controller depends only on CartService, and not on ICartRepository. Therefore, it seems to me that I cannot invert the control here if the CartController determines which interfaces CartService and ICartRepository will be used, since CartService and CartRepository are completely different. Am I right?
One level and the same question. CartService is dependent on CartRepository. Does the aforementioned inversion principle apply here? Or have I already inverted the dependency, requiring the parameter ICartRepository entered in the CartService constructor?
So, my question is actually, did I do it “right”?
Any thoughts or advice would be appreciated.
My code is for reference:
CartController:
//constructor public CartController(ICartService cartService, IProductService productService) { _cartService = cartService; _productService = productService; } public RedirectToRouteResult AddItem(Cart cart, int productId) { var product = _productService.GetProduct(productId); if (product != null) { _cartService.AddItem(cart, product, 1); } return RedirectToAction("Index"); }
CartService (implementation):
//constructor public CartService(ICartRepository repository) { _repository = repository; } public void AddItem(Cart cart, Product product, int quantity) { //simplified for brevity var cartProduct = _repository.CartProducts().SingleOrDefault(cp => cp.CartId == cart.CartId && cp.ProductId == product.ProductId); _repository.AddCartItem(cartProduct); }
Cart repository (implementation):
public void AddCartItem(CartProduct cartProduct) { _context.CartProducts.Add(cartProduct); _context.SaveChanges(); }