2016-12-01 22 views
6

Tôi khá mới đối với Dagger 2. Tôi đang cố triển khai nó trong dự án Android của mình. Tôi có số Service cần GoogleApiClient. Tôi đang sử dụng Dagger để tiêm nó vào dịch vụ này.Dagger 2: Thành phần phụ thuộc vào nhiều hơn một thành phần phạm vi

@FragmentScoped 
@Component(dependencies = {NetComponent.class, RepositoryComponent.class}) 
public interface CustomServiceComponent { 
    void inject(CustomService customService); 
} 

@Singleton 
@Component(modules = {AppModule.class, NetModule.class}) 
public interface NetComponent { 
    GoogleApiClient getGoogleApiClient(); 
} 

@Singleton 
@Component(modules = {AppModule.class, RepositoryModule.class}) 
public interface RepositoryComponent { 
    DatabaseService getDatabaseService(); 
} 

AppModule, NetModuleRepositoryModule có phương pháp đánh dấu @Singleton @Provides Khi tôi xây dựng dự án của tôi, tôi nhận được lỗi này:

The locationServiceComponent depends on more than one scoped component: @Singleton NetComponent @Singleton RepositoryComponent

Tôi hiểu tôi LocationComponent không thể phụ thuộc vào hai @Singleton scoped thành phần nhưng tôi cần cả hai của họ trong dịch vụ của tôi và cả hai cần phải là @Singleton.

Có cách nào khác thay thế tốt hơn để làm điều tương tự không?

+0

"Tôi hiểu LocationComponent của tôi không thể phụ thuộc vào hai thành phần @Singleton scoped" -> Bạn có thể giải thích lý do tại sao điều này là không thể? –

Trả lời

6

Hãy lưu ý rằng mặc dù bạn có thể có nhiều thành phần được đánh dấu @Singleton chu kỳ cuộc sống của chúng sẽ theo các chu kỳ của lớp mà bạn giữ nguyên tham chiếu của thành phần.

Điều này có nghĩa là nếu bạn khởi tạo và giữ lại NetComponentRepositoryComponent trong một Hoạt động, nó sẽ tuân theo vòng đời của Hoạt động đó và sẽ không thực sự là một ứng dụng đơn lẻ.

Do đó, có thể bạn sẽ không cần nhiều hơn một thành phần @Singleton trong ứng dụng Android. Hãy xem xét việc kết hợp hai thành phần Singleton của bạn thành một thành phần như thế này:

@Component(modules = {AppModule.class, NetModule.class, RepositoryModule.class}) 
@Singleton 
public interface AppComponent { 
    GoogleApiClient getGoogleApiClient(); 

    DatabaseService getDatabaseService(); 
} 

Sau đó, chắc chắn rằng bạn giữ lại phần @Singleton này ở cấp ứng dụng và làm cho nó có sẵn để sử dụng trong các thành phần phụ thuộc được khởi tạo ở cấp độ của Fragment hoặc hoạt động.

public class MyApp extends Application { 

    private final AppComponent appComponent; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     appComponent = DaggerAppComponent.builder() 
          //modules if necessary 
          .build(); 
    } 

    public AppComponent getAppComponent() { 
     return appComponent; 
    }     
} 

Lưu ý rằng chừng nào bạn @FragmentScoped không có bất kỳ thành phần phụ thuộc bản thân, bạn vẫn có thể tạo bao nhiêu trong số này theo ý muốn.

Lưu ý rằng mặc dù một thành phần duy nhất hiện đang tiêm GoogleApiClientDatabaseService bạn vẫn đạt được sự phân tách mối quan tâm vì chúng được cung cấp trong các Mô-đun Dagger 2 riêng biệt.

+0

Đó là giải pháp này bẩn. Bạn AppComponent chia sẻ tất cả các mô-đun, thay vào đó tôi muốn để có thể soạn thành phần của tôi từ nhiều người khác tùy thuộc vào cấu hình cần thiết và nhu cầu của thành phần được cung cấp. Làm thế nào để làm điều đó? crysis giới thiệu cấu trúc tốt – murt

+0

@murt ông đang cố gắng cung cấp phụ thuộc singleton ở một phạm vi không singleton. Điều đó sẽ không hoạt động. Bạn đúng là anh ta cần phải tái cơ cấu, nhưng anh ta cần nhóm các thành phần theo phạm vi - một thành phần phạm vi ứng dụng duy nhất và sau đó là các thành phần phụ hoặc các thành phần phụ thuộc ở cấp độ hoạt động hoặc phân đoạn. –

+0

@murt bạn có thể xem một số câu trả lời khác bằng cách sử dụng các thành phần phụ thuộc https://stackoverflow.com/a/40751767/5241933 –

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