I am trying to apply Strategy
pattern (which I think I get it wrong) using Spring as following
My main class looks like
@Component
public class DirectoryUserImportWorkflow {
private List<DirectoryUserDataSource> dataSources = Arrays.asList(new ActiveDirectoryDataSource(), new CsvDataSource());
@Autowired
private DirectoryUsersFetcher directoryUsersFetcher;
public void run() {
dataSources.forEach(dataSource -> directoryUsersFetcher.importUsers(dataSource));
}
}
where DirectoryUsersFetcher
is an interface as
public interface DirectoryUsersFetcher {
Iterator<String> importUsers(DirectoryUserDataSource dataSource);
}
with 2 implementations as
@Component
public class ActiveDirectoryUsersFetcher implements DirectoryUsersFetcher {
public Iterator<String> importUsers(DirectoryUserDataSource dataSource) {
System.out.println("Returning data from Active Directory");
return Arrays.asList("ActiveDirectoryUser1", "ActiveDirectoryUser2", "ActiveDirectoryUser3").iterator();
}
}
and
@Component
public class CsvUsersFetcher implements DirectoryUsersFetcher {
public Iterator<String> importUsers(DirectoryUserDataSource dataSource) {
System.out.println("Returning data from CSV");
return Arrays.asList("CsvUser1", "CsvUser2", "CsvUser3").iterator();
}
}
I want one of them to be used at Runtime based on what the DataSourceType
is
public enum DataSourceType {
DirectoryServer,
Csv
}
The DataSource
itself is an interface which looks like
public interface DirectoryUserDataSource {
DataSourceType getType();
}
with 2 implementations as
public class ActiveDirectoryDataSource implements DirectoryUserDataSource {
public DataSourceType getType() {
return DataSourceType.DirectoryServer;
}
}
and
public class CsvDataSource implements DirectoryUserDataSource {
public DataSourceType getType() {
return DataSourceType.Csv;
}
}
My test
looks like
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {DirectoryUserImportWorkflow.class, ActiveDirectoryUsersFetcher.class, CsvUsersFetcher.class})
public class DirectoryUserImportWorkflowTest {
@Autowired
private DirectoryUserImportWorkflow workflow;
@Test
public void runStrategy() throws Exception {
workflow.run();
}
}
What I see is
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'directoryUserImportWorkflow': Unsatisfied dependency expressed through field 'directoryUsersFetcher': No qualifying bean of type [com.learner.datafetcher.DirectoryUsersFetcher] is defined: expected single matching bean but found 2: activeDirectoryUsersFetcher,csvUsersFetcher; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.learner.datafetcher.DirectoryUsersFetcher] is defined: expected single matching bean but found 2: activeDirectoryUsersFetcher,csvUsersFetcher
How can I solve this problem?
What I need?
Based on what DataSource
is ActiveDirectory
or Csv
, the specific fetcher should invoke ActiveDirectoryUsersFetcher
or CsvUsersFetcher
Where am I missing the understanding?
Thanks in advance