2015-02-27 17 views
7

Tôi đang thử lần đầu tiên và sau khi định cấu hình mô-đun, tôi gặp phải lỗi mà tôi không hiểu.Dagger: lớp học không thể bị ràng buộc với khóa

Mã của tôi là:

public class Parrot { 

    private Language language; 

    @Inject 
    public Parrot(Language language) { 
     this.language = language; 
    } 

    public void sayHello() { 
     System.out.println(language.getSalute()); 
    } 
} 

public interface Language { 
    public String getSalute(); 
} 

public class EnglishLanguage implements Language { 

    @Override 
    public String getSalute() { 
     return "Hello!"; 
    } 
} 

mô-đun của tôi là

@Module(
     injects = Language.class 
) 
public class PetShopModule { 

    @Provides Parrot provideParrot(Parrot parrot){ 
     return parrot; 
    } 
} 

Và trong đoạn code tôi sử dụng nó theo cách này

EnglishLanguage lang=SystemApp.getSystemLanguage(); 
ObjectGraph objectGraph = ObjectGraph.create(new PetShopModule()); 
objectGraph.inject(myLanguage); 
Parrot parrot = objectGraph.get(Parrot.class); 

Trình biên dịch phàn nàn với:

error: com.example.petshop.Language could not be bound 
with key com.example.petshop.Language required by com.example.petshop.PetShopModule 
for com.example.petshop.PetShopModule 

Tôi làm gì sai?

Lưu ý: Đây chỉ là một ví dụ đơn giản, trong đoạn code thực sự EnglishLanguage là một lớp hệ thống, và tôi không thể thay đổi cũng không tạo ra nó, chỉ cần có được một tài liệu tham khảo

Trả lời

13

Thay vì bình luận về những gì bạn đang làm sai, hãy đưa ra ví dụ chính xác và giải thích những gì đang xảy ra ở đó.

đoạn này là hoàn hảo, và vẫn như nó là:

public class Parrot { 

    private Language language; 

    @Inject 
    public Parrot(Language language) { 
     this.language = language; 
    } 

    public void sayHello() { 
     System.out.println(language.getSalute()); 
    } 
} 

public interface Language { 
    public String getSalute(); 
} 

public class EnglishLanguage implements Language { 

    @Override 
    public String getSalute() { 
     return "Hello!"; 
    } 
} 

Với @Inject chú thích trên các nhà xây dựng Parrot, bạn đang nói với Dagger, "Bất cứ khi nào tôi yêu cầu một thể hiện của Parrot, sử dụng constructor này để khởi tạo nó ".

Dagger thấy rằng Parrot cần một phiên bản của giao diện Language và cố gắng tìm cách lấy lại. Tuy nhiên, vì Language là một giao diện, Dagger cần biết loại bê tông nào để sử dụng.

Vì bạn không thể sửa lại lớp EnglishLanguage, bạn sẽ cần phải viết một phương pháp @Provider cho nó:

@Module 
public class PetshopModule { 

    @Provides 
    Language provideLanguage() { 
    return SystemApp.getSystemLanguage(); 
    } 
} 

Bây giờ, bạn sẽ có thể để có được một thể hiện của Parrot ra khỏi ObjectGraph của bạn, như thế này :

ObjectGraph graph = ObjectGraph.create(new PetshopModule()); 
Parrot parrot = graph.get(Parrot.class); 

Tôi chưa thử nghiệm điều này, bit này sẽ hoạt động.


Nếu bạn thể sửa đổi các lớp EnglishLanguage, bạn có thể làm như sau. Chú thích các nhà xây dựng EnglishLanguage với @Inject, và yêu cầu một thể hiện EnglishLanguage trong phương pháp Language nhà cung cấp:

public class EnglishLanguage implements Language { 

    @Inject 
    public EnglishLanguage() { 
    } 

    @Override 
    public String getSalute() { 
    return "Hello!"; 
    } 
} 

@Module 
public class PetshopModule { 

    @Provides 
    Language provideLanguage(EnglishLanguage language) { 
    return language; 
    } 
} 

Trong trường hợp này, Dagger sẽ tìm kiếm các phương pháp cung cấp Language, và instantiates một EnglishLanguage trở lại.

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