2011-08-03 40 views
9

Tôi bắt đầu với MVC3 và muốn sử dụng một số kiến ​​trúc linh hoạt, vì vậy tôi đã đọc hàng chục blog, một cuốn sách (Pro ASP.NET MVC 3), đọc về nguyên tắc SOLID và cuối cùng đã đến một cấu trúc ứng dụng tôi thích (hoặc ít nhất là tôi nghĩ vậy, cho đến nay, bởi vì tôi đã không được xây dựng bất cứ điều gì về nó chưa):Sử dụng Ninject trong kiến ​​trúc ứng dụng SOLID

enter image description here

Trong cấu trúc này:

  • miền giữ các lớp POCO và định nghĩa các giao diện dịch vụ
  • Dịch vụ thực hiện các giao diện dịch vụ và xác định kho giao diện
  • dữ liệu thực hiện các kho giao diện
  • WebUI và Domain sử dụng Dịch vụ
  • Dịch vụ sử dụng Repositories
  • WebUI, Dịch vụ và dữ liệu phụ thuộc vào tên miền cho các lớp POCO

Lý do chính cho Dịch vụ sử dụng tên miền là xác thực các khóa duy nhất trên các phương thức Xác thực của các lớp POCO (IValidatable).

tôi bắt đầu xây dựng một ứng dụng tài liệu tham khảo với cấu trúc này nhưng tôi đã phải đối mặt, cho đến nay, hai vấn đề:

  1. Tôi đang sử dụng một dự án Data.Tests với các unit test cho các kho, nhưng chưa tìm được cách nào để tiêm (sử dụng Ninject) thực hiện dịch vụ (trong constructor hay cách khác) trên mô hình, vì vậy phương thức Validate có thể gọi CheckUniqueKey trên dịch vụ.

  2. Tôi chưa tìm thấy bất kỳ tham chiếu nào về việc đưa Ninject lên dự án TEST (rất nhiều cho dự án WebUI).

Điều tôi đang cố gắng đạt được ở đây là chuyển từ EF sang một thứ khác như DAPPER, bằng cách thay đổi hội đồng DATA.

CẬP NHẬT

Ngay bây giờ (tính 09-Aug-2011) Ninject đang làm việc nhưng tôi nghĩ rằng tôi là thiếu một cái gì đó.

Tôi có một CustomerRepository với hai cấu trúc:

public class CustomerRepository : BaseRepository<Customer>, ICustomerRepository 
{ 
    // The repository usually receives a DbContext 
    public CustomerRepository(RefAppContext context) 
     : base(context) 
    { 
    } 

    // If we don't receive a DbContext then we create the repository with a defaulte one 
    public CustomerRepository() 
     : base(RefApp.DbContext()) 
    { 
    } 

    ... 
} 

Trên TestInitialize:

// These are for testing the Repository against a test database 

[TestInitialize()] 
public void TestInitialize() 
{ 
    // Context used for tests 
    this.context = new RefAppContext(); 

    // This is just to make sure Ninject is working, 
    // would have used: repository = new CustomerRepository(context); 

    this.kernel = NinjectMVC3.CreateKernel(); 

    this.kernel.Rebind<ICustomerRepository>().To<CustomerRepository>().WithConstructorArgument("context", context); 

    this.repository = kernel.Get<ICustomerRepository>(); 

} 

Trên lớp khách hàng:

public class Customer : IValidatableObject 
{ 
    ... 

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
    { 
     // I want to replace this with a "magic" call to ninject 
     CustomerRepository rep = new CustomerRepository(); 

     Customer customer = rep.GetDupReferenceCustomer(this); 

     if (customer != null) 
      yield return new ValidationResult("Customer \"" + customer.Name + "\" has the same reference, can't duplicate", new [] { "Reference" }); 
    } 

    ... 
} 

Điều gì sẽ là cách tốt nhất để sử dụng Ninject trong kịch bản này?

Mọi trợ giúp sẽ được đánh giá cao.

ĐÁP, loại

tôi sẽ xem xét vấn đề này như aswered cho đến nay. Tôi có thể làm cho Ninject hoạt động, sắp xếp, nhưng có vẻ như đạt được Nguyên tắc đảo ngược phụ thuộc (DIP) của SOLID sẽ mất nhiều thời gian hơn.

Về khía cạnh đó, tôi phải gộp lại với nhau Miền, Dịch vụ và dữ liệu, tôi sẽ tạo một câu hỏi khác một thời gian khác và giữ cho dự án đi theo cách thông thường ngay bây giờ.

Cảm ơn mọi người.

+1

Đề nghị đưa ra tham chiếu Ninject và thay đổi nó thành DI làm câu trả lời sẽ không (và không nên thay đổi dựa trên vùng chứa cụ thể của bạn). Tôi cũng sẽ thêm một kiến ​​trúc hoặc tìm thêm một vài thẻ nữa. –

+0

@Ruben bạn nói đúng, nó không có vẻ khá đúng khi sử dụng "Ninject" và "kiến trúc ứng dụng" trên cùng một câu, nó chỉ trong trường hợp này tôi đang cố gắng giải quyết một vấn đề rất cụ thể cho Ninject. –

+1

Tôi muốn cập nhật vào một câu hỏi mới vì nó là một chủ đề hoàn toàn khác mà không có nhiều điểm chung với câu hỏi đầu tiên. Không có nhiều người sẽ đọc vấn đề mới của bạn nếu không. –

Trả lời

3

Kiểm tra đơn vị phải được thực hiện mà không cần Ninject. Chỉ cần tạo một thể hiện của đối tượng đang được kiểm tra và tiêm một mô hình cho mọi phụ thuộc theo cách thủ công.

Đối với kiểm tra tích hợp, bạn có thể sử dụng hạt nhân bao gồm tất cả các ràng buộc từ bootstrapper ứng dụng và rebind mọi thứ bạn muốn thay thế bằng Mock. ví dụ. Thay thế các ràng buộc phiên bằng một trong đó sử dụng một trong bộ nhớ dữ liệu lưu trữ thay vì một cơ sở dữ liệu thực sự.

+0

Hiện tại tôi đang thử nghiệm tích hợp, vì tôi đang thử nghiệm các kho lưu trữ truy cập vào DB thực tế. Việc sử dụng Ninject là để có thể cuối cùng thay thế lớp dịch vụ với đôi khi khác. Trong trường hợp này, phương thức POCO.Validate đang sử dụng một phương thức dịch vụ được định nghĩa trong một giao diện. Vấn đề là, ví dụ: làm cách nào để giải quyết giao diện dịch vụ trong phương thức Customer.Validate để tôi có thể sử dụng phương thức CustomerServices.FindCustomerByEmail (Email) để kiểm tra xem có một khách hàng khác có cùng email không. –

+0

@Miguel Veloso: Cập nhật kiểm tra tích hợp –

+0

nơi nào tôi đặt trình khởi động ứng dụng? Không có Global.asax trong một dự án thử nghiệm! –

Các vấn đề liên quan