Fragments
A @Fragment
annotated interface is used to define a subset of the components that
can contribute to a component graph modelled by an injector. The fragment does this through two mechanisms:
- The
@Fragment.includes
parameter allows the user to specify additional types that will contribute to the component graph. - The interface may include zero or more default access methods that are invoked to programmatically create
components. This technique is used when third-party objects can't be annotated, when a different framework
is responsible for creating the object (i.e
GWT.create(MyGwtRpcService.class)
or when it is awkward to create the type (i.e. when publishing a component that is provided by calling a method on another component). The documentation often terms these "provider" methods.
It is not uncommon to define a fragment that includes several other types but does not declare any provider methods. This makes it possible to include several components in an injector by just including a single fragment. This may be desirable if the application has multiple different injectors or uses different injectors when writing tests or if the components can be included in multiple independent applications.
For example:
@Fragment(
includes = { UserRepository.class,
PermissionRepository.class,
GroupRepository.class } )
public interface SecurityFragment
{
}
At other times, fragments will just include provider methods such as:
@Fragment
public interface RemoteServicesFragment
{
default UserServiceAsync getUserServiceAsync( @Named( "BaseURL" ) final String baseUrl )
{
final UserServiceAsync service = GWT.create( UserServiceAsync.class );
( (ServiceDefTarget) service ).setServiceEntryPoint( baseUrl + "api/rpc/user" );
return service;
}
default AuthorizationServiceAsync getAuthorizationServiceAsync( @Named( "BaseURL" ) final String baseUrl )
{
final AuthorizationServiceAsync service = GWT.create( AuthorizationServiceAsync.class );
( (ServiceDefTarget) service ).setServiceEntryPoint( baseUrl + "api/rpc/authorization" );
return service;
}
...
}
It is also perfectly acceptable, for a fragment to include both includes and provider methods:
@Fragment( includes = { FileSystemService.class, ParserFragment.class } )
public interface CompilerFragment
{
default Compiler getCompiler( FileSystemService fileSystemService, Parser parser )
{
return
new Compiler.Builder()
.setFileSystemService( fileSystemService )
.setParser( parser )
.setDiagnosticsReporter( new StdoutDiagnosticsReporter() )
.build();
}
...
}