Search code examples
c#asp.net-mvcdependency-injectionninject

Dependency Injection using Ninject without interface


We are working on a Mvc application, where we want to use dependency injection using nInject. Currently we are maintaining entities in different class library "ShopEntities" and in our mvc application we are using this entities. Let's consider a class in ShopEntities.

namespace ShopEntities
{
    public class Customers
    {
        public int custId {get;set;}

        public string custName {get;set;}
        public string Address {get;set;}
        public string ShippingAddress {get;set;}

    }
}

Now when we want to use it in our mvc application, we create an instance and set the properties like below,

public ActionResult Index()
{
    ShopEntities.Customers cust = new ShopEntities.Customers();
    cust.CustName = "Sam";
    cust.IAddress = "xyz";
    cust.ShippingAddress = "xyz xyx xyz"; 

}

How to use nInject here to avoid dependency? Further we don't want to create interfaces as this is limited in scope. Thanks in advance.


Solution

  • The way to abstract away the use of the Customer entity from the presentation layer is not to hide the entity itself behind an ICustomer of some sort, nor to let a DI container build it up. Hiding data objects behind an interfaces is typically not useful; interfaces are meant to abstract behavior, not data.

    As NightOwl already stated, your Customer entity is runtime data and you should not use a container to build up object graphs containing runtime data.

    Instead, you should hide specific business operations behind an abstraction. Such abstraction can be consumed by the presentation layer and implemented by the business layer. For instance:

    public interface ICustomerServices
    {
        void CreateCustomer(string customerName, string homeAddress, 
            string shippingAddress);
    
        void ChangeShippingAddress(Guid customerId, string shippingAddress);
    }
    

    Your controller can depend on this abstraction:

    private readonly ICustomerServices customerServices;
    
    public CustomerController(ICustomerServices customerServices) {
        this.customerServices = customerServices;
    }
    
    public ActionResult Index()
    {
        this.customerServices.CreateCustomer("Sam", "xyz", "xyz xyz xyz");
    }
    

    Now your business layer can create an implementation for this abstraction that uses the entities internally:

    public class CustomerServices : ICustomerServices
    {
        private readonly EntitiesContext context;
    
        public CustomerServices(EntitiesContext context) {
            this.context = context;
        }
    
        public void CreateCustomer(string customerName, string homeAddress,
            string shippingAddress)
        {
            // NOTE that I renamed 'Customers' to 'Customer', since it holds information
            // to only one customer. 'Customers' implies a collection.
            Customer cust = new ShopEntities.Customer();
            cust.CustName = "Sam";
            cust.IAddress = "xyz";
            cust.ShippingAddress = "xyz xyx xyz"; 
    
            this.context.Customers.Add(cust);
    
            this.context.SubmitChanges();
        }
    
        public void ChangeShippingAddress(...) { ... }
    }
    

    Doing this has the advantage that you can keep your presentation layer thin, but there are still quite some down sides to the shown approach, compared to alternatives. One of such alternatives is using a message based approach with SOLID design, as explained here.