Auto Discovery Pattern¶
When developing Framework Modules, sometimes we provide interfaces for consumers to implement. Or we are wrapping a third party library which has some useful types like AutoMapper.Profile, etc.
This pattern is quite similar to the Provider Pattern. Actually, the Provider Pattern can be implemented using Auto Discovery instead of DI. The Auto Discovery pattern's advantage is that it allows you to modify or inspect the types before registering them into DI.
The goal is always to automatically discover all these types from all registered
modules at runtime, instead of having consumers having to call a method to add
these implementations. Again, AutoMapper.Profile is a good example: you just
implement a class which extends from Profile
and it gets automatically
discovered, if you depend on the AutoMapperModule
, of course.
In order to implement this, we have two ground rules:
- Keep ModuleOptions as the source of truth
- Use the discovered types as late as possible.
Auto Discovery Module Options¶
The Auto Discovery pattern consist of a Module Options which includes the list of types that were discovered or manually added.
Module Options should include a, usually internal, ICollection<Type>
and
public convenience methods for adding types, like using generics.
They should also include a bool for toggling each auto discovery of types (if
multiples are provided), and a method, DisableAllAutoDiscovery()
, to disable
them all. This is quite useful for testing purposes, where you only want a set
of types to be included in the test case.
When disabling auto discovery, the convenience methods for adding types are used.
Let's see an example. Say we have this interface that we want to discover all its implementors:
C# | |
---|---|
Our module options may look like this:
Then, in our module we would use this like so: