[英]Inject Dependency without using Constructor injection using Ninject - Unit Tests
[英]Dependency Injection using Ninject without interface
我們正在開發一個Mvc應用程序,我們想在其中使用nInject進行依賴注入。 當前,我們在不同的類庫“ ShopEntities”中維護實體,在我們的mvc應用程序中,我們正在使用該實體。 讓我們考慮一下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;}
}
}
現在,當我們想在mvc應用程序中使用它時,我們創建一個實例並設置如下所示的屬性,
public ActionResult Index()
{
ShopEntities.Customers cust = new ShopEntities.Customers();
cust.CustName = "Sam";
cust.IAddress = "xyz";
cust.ShippingAddress = "xyz xyx xyz";
}
如何在這里使用nInject以避免依賴? 此外,我們不想創建接口,因為它的范圍受到限制。 提前致謝。
從表示層中抽象出對Customer
實體的使用的方法既不是將實體本身隱藏在某種ICustomer
的后面,也不是讓DI容器構建它。 將數據對象隱藏在接口后面通常是沒有用的。 接口用於抽象行為,而不是數據。
作為夜鷹已經指出 ,您的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(...) { ... }
}
這樣做的好處是可以使表示層保持較薄,但是與替代方法相比,所示方法還有很多缺點。 一個這樣的替代品使用具有雄厚的設計基於消息的方法,因為解釋在這里 。
如果我理解您的問題,則應創建中間業務層以將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
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.