15

Tôi đã học IoC, Dependency Injection vv và tận hưởng quá trình này. Lợi ích của việc tách và lập trình thành các giao diện là, đối với tôi, không có trí tuệ.Làm thế nào để Decouple IoC Framework thực hiện

Tuy nhiên, tôi thực sự không thích ràng buộc mình vào một khuôn khổ cụ thể như Unity hoặc Autofac hoặc Windsor - bởi vì tôi vẫn đang học và chưa quyết định cái nào là tốt nhất cho mục đích của tôi.

Vì vậy, làm thế nào tôi có thể bọc xung quanh một cái gì đó như Unity vì vậy tôi có thể dễ dàng trao đổi tại Windsor vào một ngày sau đó? (hay bất cứ cái gì). Và bạn không dám nói sử dụng một cái khác để tiêm cái đầu tiên;)

Cảm ơn!

R.

P.s. Tôi đã gắn thẻ Unity vì đó là sở thích cá nhân hiện tại của tôi (tôi chỉ lén lút Entlib).

Trả lời

18

Bạn chắc chắn có thể thử tạo trừu tượng từ vùng chứa bằng cách khai báo IContainer với số ResolveRegister. Tôi đã làm điều đó một vài lần. Sau đó, bạn sẽ tiếp tục và triển khai một Container : IContainer và đóng gói một thùng chứa IoC thực tế với sự trừu tượng của bạn. Tôi đã thử với Unity và Castle Windsor.

Nhưng hey, tôi nhận ra rằng đây thực sự là một kỹ thuật quá mức. Sau đó tôi hiểu rằng tôi đã cố gắng trừu tượng hóa từ trừu tượng, nhưng để xây dựng một trừu tượng khác. Điều này có thể là tốt để học khái niệm, nhưng đó là một nỗi đau thực sự ở cổ trong một dự án thực sự. Tôi rất khuyên bạn nên chống lại một trừu tượng từ container IoC. Nếu bạn sử dụng đúng nguyên tắc DI, nó sẽ khá dễ dàng để thay đổi anyways container của bạn.

Mã này trông overcomplicated, như

//I did this mess with Service Locator 
var t = ContainerService.Instance.Resolve<IMyType>(); 
//others could go further with same Service Locator 
var t = IoCFactory.Instance.CurrentContainer.Resolve<IMyType>(); 

//better way, use --> IoC and DI <-- 
//when a program starts, or a new instance of the context created 
var t = Container.Resolve<IMyType>() //this lives at the bottom of the stack 
//and then you just pass IMyType to the constructor of other types  
//you don't need to call Resolve again in the logical cycle 

Xem this post bởi Ayende.

Có, họ đã tóm tắt Vùng chứa kiểm soát ngược. Tôi nghĩ rằng nếu bạn cần phải làm điều đó, nó là khá rõ ràng rằng bạn không thực sự có được những gì IoC là tất cả về.

+0

điểm tốt, trừu tượng IoC âm thanh như overdesign – pkmiec

+0

Bạn hoàn toàn đúng, điều này là dành cho yêu cầu học tập. Một khi tôi giải quyết trên container của tôi de jour, tôi sẽ được hạnh phúc. Nhưng khi bạn đang học và phải viết lại các ứng dụng để phục vụ cho một container khác bởi vì ví dụ trên blog đang sử dụng x thay vì y, nó sẽ được bạn sau một thời gian. Tôi nghĩ sẽ tốt hơn nếu có ví dụ của riêng tôi và chỉ tìm ra cách dễ dàng trao đổi bất kỳ vùng chứa nào mà blog đang sử dụng để minh họa một khái niệm cụ thể. – Richard

+0

Tôi đồng ý, điều này là quá mức cần thiết. Một container IoC phong nha nên có nhiều chỗ cho cấu hình để bạn không phải gây ô nhiễm mã của bạn với các tham chiếu đến container. Nếu abstracting container là cách duy nhất để làm cho nó hoạt động, sau đó tôi muốn nói rằng bạn đang sử dụng một container IoC nghèo. – FMM

3

Khám phá thư viện Common Service Locator.

+6

imho, CSL thực sự chỉ hữu ích khi xây dựng một thành phần sẽ được sử dụng trên nhiều dự án khác nhau mà bản thân họ có thể chọn sử dụng các thư viện IoC khác nhau. Ví dụ, việc sử dụng CSL trong ứng dụng kinh doanh đơn lẻ của họ là quá mức cần thiết. Nó cho biết thêm rất nhiều trong quản lý phụ thuộc và chỉ cung cấp một giao diện rất hẹp có thể chỉ đơn giản là cụ thể trong một cơ sở hạ tầng lõi của chính ứng dụng. –

+3

Là một trong những nhà thiết kế của CSL, tôi xác nhận chắc chắn nhận xét trên. CSL dành cho các tác giả thư viện muốn có một vùng chứa, nhưng không muốn ép buộc lựa chọn vùng chứa của thư viện trên ứng dụng. –

18

Sử dụng hàm tạo constructor để truyền đạt những phụ thuộc mà lớp cần. Mỗi vùng chứa bạn liệt kê đều hỗ trợ nó.

Đôi khi một đoạn mã không thể đạt được sự độc lập hoàn toàn của vùng chứa, nhưng những trường hợp này phải là một phần rất nhỏ trong cơ sở mã của bạn.

+5

Hoàn toàn đúng đối với việc thích tiêm constructor. – FMM

4

Như một số người khác đã đề cập, thích tiêm xây dựng. Điều này sẽ giải quyết được nhiều vấn đề của bạn.

Nếu lớp của bạn có phụ thuộc trực tiếp vào vùng chứa IoC, nó có xu hướng là biến thể của việc sử dụng mẫu định vị dịch vụ (chống). Trong trường hợp cụ thể này, cô lập các kiểu nào đang được giải quyết thông qua bộ định vị dịch vụ và trừu tượng hóa độ phân giải động đó với một giao diện nhà máy.Vì vậy, ví dụ, thay thế này:

public class Foo 
{ 
    private MyIoCContainer _container; 

    public Foo(MyIoCContainer container) 
    { 
     this._container = container; 
    } 


    public void DoSomething() 
    { 
     // have to do this at runtime for whatever reason 
     var myObj = this._container.Resolve<ISomeType>(); 

     myObj.DoSomething(); 
     myObj.DoSomethingElse(); 
    } 
} 

với điều này:

public class Foo 
{ 
    private IObjFactory _provider; 

    public Foo(IObjFactory _provider) 
    { 
     this._provider = provider; 
    } 


    public void DoSomething() 
    { 
     var myObj = _provider.GetObj(); 

     myObj.DoSomething(); 
     myObj.DoSomethingElse(); 
    } 
} 

public interface IObjFactory 
{ 
    ISomeType GetObj(); 
} 

Bây giờ, bạn có một IObjFactory rằng có thể gói gọn năng động, thời gian chạy tính chất xây dựng đối tượng mà thực hiện ISomeType. Nếu bạn đang xây dựng nhiều loại đối tượng khác nhau từ bộ định vị vùng chứa/dịch vụ, thì bạn nên có ít nhất là nhiều giao diện *Factory (theo Interface Segregation Principle).

9

Vùng chứa DI chỉ nên được tham chiếu từ Composition Root. Tất cả các mô-đun khác sẽ không có tham chiếu đến vùng chứa.

-Mark SEEMANN (tác giả của Dependency Injection in .NET)

Nói cách khác, bạn chỉ cần thay đổi một lớp nếu bạn thay đổi DI container.

Tiêm xây dựng thường là cách đi đúng, như những người khác đã đề cập. Bạn có thể tiêm giao diện nhà máy hoặc Func<T> đại biểu nếu bạn cần tạo đối tượng khi đang di chuyển.

Tôi cũng khuyên bạn nên tránh cấu hình XML bất cứ khi nào có thể.

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