2010-02-01 26 views
27

Tình huống: tôi cần sự phụ thuộc vào độ trễ phụ thuộc vào một số FooClass, vì vậy tôi chuyển Injector thành lớp làm tham số hàm tạo.Làm thế nào để tiêm Injector?

private final Injector m_injector; 

public FooClass(@Named("FooInjector") Injector injector) { 
m_injector = injector; 
} 

Nhưng guice không cho phép ràng buộc các lớp lõi (kim phun, mô-đun và v.v ...). Giải pháp là gì?

Trả lời

27

Bạn không nên trực tiếp sử dụng số Injector. Thay vào đó, hãy chuyển sang số Provider<FooClass>. Ngoài ra, bạn nên tiêm nhà cung cấp ở những nơi bạn sử dụng FooClass.

private final Provider<FooClass> provider; 

@Inject 
public ClassWhereFooIsUsed(Provider<FooClass> provider) { 
    this.provider = provider; 
} 

.... somewhere else 
FooClass f = provider.get(); // This is lazy 
+0

Thx! Tôi sẽ thử nó để khởi tạo lười biếng. Nhưng có thực sự không có cách nào để tiêm Injector? –

+6

Bạn có thể nhận được vòi phun với bộ phận phun 'InIn Injector', có thể ở trên hàm tạo/trường/phương thức. – gpampara

+0

Bạn đã thử cái này chưa? Làm thế nào cấu hình mô-đun? Guice hạn chế ràng buộc với các lớp lõi: "Ràng buộc để loại khung cốt lõi guice không được phép: Injector." –

7

Vì @gpampara cho biết, Provider<T> nên được sử dụng để khởi tạo lười/tùy chọn. Ngoài ra, như tôi đã nói trong câu trả lời của tôi cho câu hỏi khác của bạn, bạn nên tránh tham chiếu đến Injector trong mã của bạn trong hầu hết các trường hợp.

Điều đó nói rằng, trong một lớp được tạo ra bởi Guice, Injector đang tạo đối tượng có thể được tiêm chỉ bằng cách khai báo sự phụ thuộc vào Injector. Các Injector là tự động có sẵn để tiêm mà không có bạn tuyên bố bất kỳ ràng buộc cho nó.

Nếu bạn tiêm Injector, bạn nên nghĩ đến TẠI SAO bạn muốn làm điều đó. Tại sao bạn không chỉ khai báo các phụ thuộc vào các giao diện/lớp thực tế mà lớp phụ thuộc vào? Thật dễ dàng để thêm một phụ thuộc mới vào hàm tạo vì nó là để lấy ra một cá thể của một số phụ thuộc thông qua các mã khác trong mã của bạn, và nó làm cho mã dễ hiểu hơn nhiều.

+0

Re: "TẠI SAO bạn muốn làm điều đó" - Ví dụ: tôi muốn tạo proxy động khi đang di chuyển sau khi khởi động. câu hỏi của tôi về điều này: http://stackoverflow.com/questions/34252268/best-practice-for-creating-dynamic-proxies-with-guice –

8

Khi người khác đã trả lời, bạn có thể chỉ cần sử dụng @Inject Injector vì Guice xác định ràng buộc chính nó.

Thông thường, bạn chỉ cần một Injector trong ứng dụng của mình và biến tĩnh là một cách dễ dàng hơn để lưu trữ và truy cập một singleton hơn là tiêm nó. Trong ứng dụng web của chúng tôi, chúng tôi sử dụng stripes-guicer và nhận được Injector từ phương pháp tĩnh GuiceInjectorFactory.getInjector() của chúng tôi khi chúng tôi cần nó (trong bộ chặn đánh chặn Hibernate của chúng tôi).

Tôi hơi bối rối bởi lời khuyên rằng "bạn không nên sử dụng Injector trực tiếp." Làm thế nào khác tôi sẽ nhận được một trường hợp tiêm ngoại trừ bằng cách gọi injector.getInstance() hoặc injector.injectMembers()? Không có cách nào. Có, bạn có thể định nghĩa các phương thức của Nhà cung cấp, nhưng chúng sẽ không bao giờ được gọi trừ khi ở đâu đó, một cái gì đó sử dụng một Injector. Có, có các mô-đun sử dụng Bộ nạp cho bạn thích ServletModule; bạn phải tự tạo ra Injector, nhưng bạn có thể để nó cho ServletModule sau đó.

Vì vậy, trong một số trường hợp, bạn có thể tránh sử dụng Bộ phun trực tiếp, nhưng điều đó không có nghĩa là bạn "không nên" sử dụng nó. Nếu bạn đang sử dụng Guice một mình mà không có bất kỳ mô-đun tùy chọn, sau đó bạn "nên" được sử dụng một Injector trên tất cả các nơi vì không có cách nào khác để kích hoạt tiêm. (Tôi nghĩ rằng các nhà phát triển dành cả ngày viết mã bên trong khung công tác đôi khi quên rằng một số người thực sự khởi tạo các đối tượng của riêng họ.)

+3

Tôi không tin rằng bạn đã hiểu lý do đằng sau Guice. Nó chỉ nhằm mục đích tránh sử dụng các trường tĩnh và trạng thái, và bạn chỉ nên rất ít khi thực hiện một tham chiếu trực tiếp đến chính Injector. Bạn nhận được các cá thể được tiêm bằng cách khai báo các phụ thuộc với @Inject, thay vì gọi 'getInstance()' trên bộ phun. –

+12

Điểm duy nhất của tôi (mà tôi đã nói một cách chi tiết) là bạn phải bắt đầu một nơi nào đó; đó là một vấn đề về thịt gà và trứng. Bạn không thể * chỉ * trang trí các phương thức với @Inject và mong đợi bất cứ điều gì xảy ra. Một cái gì đó, ở đâu đó, phải gọi injector.getInstance() hoặc injector.injectMembers() để bắt đầu tất cả. –

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