2016-06-01 19 views
0

Wir arbeiten an einer Mvc-Anwendung, wo wir die Abhängigkeitsinjektion mit nInject verwenden möchten. Momentan pflegen wir Entitäten in verschiedenen Klassenbibliotheken "ShopEntities" und in unserer mvc-Anwendung verwenden wir diese Entitäten. Betrachten wir eine Klasse in ShopEntities.Dependency Injection mit Ninject ohne Schnittstelle

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;} 

    } 
} 

Nun, wenn wir es in unserem MVC-Anwendung verwenden möchten, erstellen wir eine Instanz und legen Sie die Eigenschaften unten wie

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

} 

Wie ninject hier verwenden Abhängigkeit zu vermeiden? Außerdem möchten wir keine Schnittstellen erstellen, da dies in ihrem Umfang begrenzt ist. Danke im Voraus.

+3

[Dependency-Injektion Anti-Pattern: Injection Laufzeitdaten in Komponenten] (https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=99). Sie sollten keine Schnittstellen erstellen oder DI für Entitäten verwenden - sie sind Laufzeitdaten. DI dient zum Erstellen von Anwendungskomponenten. – NightOwl888

Antwort

5

Der Weg zu abstrahieren die Verwendung der Customer Entität aus der Präsentationsschicht nicht zu verbergen ist die Entität selbst hinter einem ICustomer irgendeiner Art, noch einen DI-Container aufbauen zu lassen. Das Ausblenden von Datenobjekten hinter Schnittstellen ist normalerweise nicht sinnvoll. Schnittstellen sollen das Verhalten, nicht die Daten abstrahieren.

Wie NightOwl bereits stated, Ihre Customer Entität Daten Laufzeit und Sie sollten nicht einen Behälter verwenden, um Objektgraphen enthält Laufzeitdaten aufzubauen.

Stattdessen sollten Sie bestimmte Geschäftsvorgänge hinter einer Abstraktion verbergen. Eine solche Abstraktion kann von der Präsentationsschicht konsumiert und von der Business-Schicht implementiert werden. Zum Beispiel:

public interface ICustomerServices 
{ 
    void CreateCustomer(string customerName, string homeAddress, 
     string shippingAddress); 

    void ChangeShippingAddress(Guid customerId, string shippingAddress); 
} 

Ihr Controller auf dieser Abstraktion verlassen können:

private readonly ICustomerServices customerServices; 

public CustomerController(ICustomerServices customerServices) { 
    this.customerServices = customerServices; 
} 

public ActionResult Index() 
{ 
    this.customerServices.CreateCustomer("Sam", "xyz", "xyz xyz xyz"); 
} 

Jetzt ist Ihre Business-Schicht eine Implementierung für diese Abstraktion schaffen, die die Entitäten intern verwendet:

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 Dies hat den Vorteil, dass Sie Ihre Präsentationsschicht dünn halten können, aber es gibt immer noch einige Nachteile gegenüber dem gezeigten Ansatz, verglichen mit Alternativen. Eine dieser Alternativen ist die Verwendung eines auf Nachrichten basierenden Ansatzes mit SOLID-Design, wie es in here erläutert ist.

0

Wenn ich Sie Fragen zu verstehen, sollten Sie Mitte Business-Schicht erstellen ShopEntities zu Ihrer eigenen Einheiten zu konvertieren:

namespace MyShopEntities 
{ 
    public class MyCustomers 
    { 
     public int custId {get;set;} 

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

    } 
} 

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

} 

class BussinesModel 
{ 
    void Insert(ShopEntities.Customer customer) 
    { 
    // use ShopEntities.Customer only in wrapper 
    // if you later switch to another Customer dependency, 
    // you just change this  wrapper 

    MyShopEntities.MyCustomers cust = new MyShopEntities.MyCustomers(); 
    cust.CustName = customer.CustName; 
    cust.IAddress = customerIAddress; 
    cust.ShippingAddress = customer.ShippingAddress; 
    InsertInternal(cust); 
    } 

    void InsertInternal(MyShopEntities.MyCustomer customer) 
    { 
     // use MyCustomer for all your bussines logic 
    } 
} 
Verwandte Themen