2010-06-17 38 views
5

Tôi đang cố gắng để bắt đầu với một số tiêm phụ thuộc đơn giản bằng cách sử dụng C# và tôi đã chạy lên chống lại một vấn đề mà tôi dường như không thể đưa ra một câu trả lời cho.C# phụ thuộc tiêm - làm thế nào để bạn tiêm một phụ thuộc mà không có nguồn?

Tôi có một lớp học được viết bởi một bộ phận khác mà tôi không có nguồn trong dự án của mình. Tôi muốn tiêm một đối tượng kiểu này mặc dù một constructor sử dụng một giao diện, nhưng tất nhiên, tôi không thể thay đổi việc thực hiện các đối tượng được tiêm để thực hiện giao diện để đạt được đa hình khi truyền đối tượng sang kiểu giao diện.

Mỗi ví dụ học tập mà tôi từng thấy về kỹ thuật này đều có các lớp sử dụng các lớp được khai báo trong chính dự án. Làm thế nào tôi sẽ đi về tiêm chích sự phụ thuộc của tôi mà không có nguồn có sẵn trong dự án?

Tôi hy vọng điều đó có ý nghĩa, cảm ơn.

Trả lời

0

Nếu bạn không có nhu cầu thay đổi bất kỳ thứ gì trong lớp học, bạn hầu như không cần mã. Giả sử bạn có một lớp X trong một DLL mà bạn muốn tiêm vào một lớp Y khác mà bạn đang viết. Trong trường hợp này bạn có thể tạo một thể hiện của X và đặt làm tham số trong hàm tạo của Y. Điều này sẽ trông giống như sau:

Thêm tham chiếu đến DLL chứa lớp X trong dự án của bạn.

Use NameSpaceOfX; 
Class Y 
{ 
    Public Y() //Default constructor 
    { 
    } 

    Public Y(X instanceOfX) 
    { 
     //Use instanceOfX here as required 
    } 
} 

Trong bạn mã chính:

//Create instance of X 
X instanceOfX = new X(); 
//Inject it into Y 
Y instanceOfY = new Y(instanceOfX); 
//Use Y now. 
6

Bạn có thể tạo một wrapper xung quanh loại mục tiêu của bạn, ví dụ như vậy, bạn có thể có một lớp học mà họ cung cấp:

public class TheirClass 
{ 
    public void DoSomething(); 
} 

Với mà bạn có thể xác định giao diện:

public interface ITheirClass 
{ 
    void DoSomething(); 
} 

Và thực hiện mà giao diện trên một lớp wrapper:

public class TheirClassWrapper : TheirClass, ITheirClass 
{ 

} 

Hoặc, nếu lớp họ đã cung cấp được bịt kín, bạn cần phải làm điều đó hơi khác nhau:

public class TheirClassWrapper : ITheirClass 
{ 
    private TheirClass instance = new TheirClass(); 

    public void DoSomething() 
    { 
    instance.DoSomething(); 
    } 
} 

Sau đó, bạn có thể tiêm giao diện đó để thay thế.

Tôi biết trong MEF, chúng tôi có thể xuất các loại bê tông và tiêm chúng đúng cách, nhưng tôi không chắc chắn về các thùng chứa IoC khác.

+0

Đây là chính xác những gì tôi đã suy nghĩ. – Steven

+0

Mẫu bộ điều hợp. Cuộc gọi tốt. – Wix

1

Câu hỏi đặt ra là, tại sao bạn muốn tiêm nó làm giao diện? Có phải vì lớp thực hiện một số thuộc tính/phương thức mà bạn muốn trừu tượng hóa để có thể thay thế hoặc bạn chỉ cố gắng "buộc" giao diện điểm đánh dấu vào nó bởi vì "chúng tôi luôn phụ thuộc vào giao diện chứ không phải các lớp cụ thể" ? Nếu đó là sau này thì bạn đang trên con đường sai lầm như bạn có thể chỉ cần đúc nó vào bê tông ngay lập tức anyway.

Giả sử trước đây của hai tôi có thể nhìn thấy hai lựa chọn:

  1. Sử dụng thừa kế để thay thế. Điều này có thể hoặc không thể tùy thuộc vào lớp đã được tạo, nhưng bạn có thể kế thừa từ nó và thay thế lớp mới của bạn cho lớp cũ.
  2. Tự tạo giao diện, với các phương thức/thuộc tính bạn yêu cầu và bọc lớp bê tông ngoài trong một lớp thực hiện giao diện.

Đối với tùy chọn 2, nếu bạn không thể kế thừa, ví dụ, giả sử bạn chỉ quan tâm đến một phương pháp trong lớp (chúng tôi gọi nó là Method1()) bạn tạo giao diện phù hợp cho nó:

public interface IMyNewInterface 
{ 
    void Method1(); 
} 

Sau đó tạo một thực hiện của nó mà có lớp bê tông như một sự phụ thuộc (tiêm bằng container của bạn như bình thường) mà chỉ gọi là lớp bê tông:

public class MyNewClass : IMyNewInterface 
{ 
    private MyConcreteClass _MyConcreteClass; 

    public void MyNewClass(MyConcreteClass concreteClass) 
    { 
     _MyConcreteClass = concreteClass; 
    } 

    public void Method1() 
    { 
     _MyConcreteClass.Method1(); 
    } 
} 
+0

Nhưng với tùy chọn thứ hai của hai tùy chọn, bạn có thể kiểm tra đơn vị lớp của riêng bạn sử dụng lớp bên thứ 3 làm đối số được truyền cho hàm tạo. tức là nó sẽ có thể để mô phỏng của họ với ITheirClass –

+0

Cả hai tùy chọn cho phép bạn thay thế lớp của họ (generics sang một bên), cách tiếp cận giao diện sẽ là sở thích của tôi mặc dù. –

+0

Xin lỗi, tôi không có nghĩa là các tùy chọn 1 và 2. Đề cập đến câu "..chúng tôi luôn luôn phụ thuộc ...". Có lẽ tôi đã hiểu sai. Có lẽ bạn có nghĩa là nó không nên được thực hiện chỉ vì lợi ích của việc được thực hiện. Nhưng thực hành tốt có nghĩa là chúng ta làm mịn đường cho những thay đổi hoặc bảo trì trong tương lai. Nếu lớp học đã được tiêm thì nó sẽ làm cho nó dễ dàng hơn để tiêm nó với ví dụ như đo lường hiệu suất aop ?? –

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