2016-06-01 19 views
0

私たちは、nInjectを使用して依存性注入を使用するMvcアプリケーションに取り組んでいます。現在、私たちは異なるクラスライブラリ "ShopEntities"のエンティティを維持しており、私たちのmvcアプリケーションでは、このエンティティを使用しています。 ShopEntitiesのクラスについて考えてみましょう。インタフェースなしのNinjectを使用した依存性注入

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

    } 
} 

今、私たちは私たちのMVCアプリケーションでそれを使用したい場合、我々は、インスタンスを作成し、以下のようなプロパティを設定し、

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

} 

依存することを避けるため、ここでnInjectを使用する方法?さらに、これは範囲が限定されているため、インタフェースを作成したくありません。前もって感謝します。

+3

[Dependency-injection anti-pattern:コンポーネントへのランタイムデータの注入](https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=99)エンティティのインタフェースを作成したりDIを使用したりしないでください。これらは実行時データです。 DIはアプリケーションコンポーネントを構成するためのものです。 – NightOwl888

答えて

5

をプレゼンテーション層からCustomerエンティティの使用を抽象化への道を非表示にすることではありませんエンティティ自体はある種のICustomerの背後にあり、DIコンテナにそれを構築させることもできません。インタフェースの背後にあるデータオブジェクトを隠すことは、一般的には有用ではありません。インタフェースとは、データではなく、抽象的な動作を意味します。 NightOwlすでにstatedとして

、あなたのCustomerエンティティは、ランタイムデータであり、あなたがは、ランタイムデータを含むオブジェクトグラフを構築するための容器を使用しないでください。

代わりに、抽象化の背後にある特定のビジネス操作を非表示にする必要があります。そのような抽象化は、プレゼンテーション層によって消費され、ビジネス層によって実装されることができる。例えば:

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

    void ChangeShippingAddress(Guid customerId, string shippingAddress); 
} 

あなたのコントローラは、この抽象化に依存することができます

private readonly ICustomerServices customerServices; 

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

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

今すぐあなたのビジネス層が内部エンティティを使用して、この抽象化のための実装を作成することができます

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(...) { ... } 
} 
行う

これは、プレゼンテーションレイヤーを薄く保つことができるという利点がありますが、代替案と比較して、示されたアプローチにはかなりの面があります。このような代替案の1つは、hereのように、SOLID設計のメッセージベースのアプローチを使用することです。

0

私はあなたが質問を理解している場合、あなたはあなた自身のエンティティにShopEntitiesを変換するために、中央ビジネスレイヤを作成する必要があります

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 
    } 
} 
関連する問題