Some notes on component injection.
Either the entry point class or any component class can require and receive an instance of a component.
Snow offers two ways of doing this: Autowired Properties and Autowired Constructors. Note that you can combine these two alternatives at will.
Also, keep in mind that all component injections are performed prior to execution. If this process fails, Snow will abort and throw an exception. Thus, you don't need to check injected dependencies for null values.
Easy, short, and to the point.
Start by adding a property or field to your component class, and mark it with the [Autowired] attribute:
// Either a [Component] or the Program entry point public class ExecutingClass { [Autowired] private NumbersService numbers; public void Run() { var result = numbers.Sum(4, 5); } }
This is really all you need. When you execute this program, Snow will fill the property with a valid instance of NumbersService that you can use.
Autowired properties can be public, internal or private, and you can even make them readonly to get an immutable component, and it will work just the same.
A more structured and formalist approach.
Autowired constructors mimic other IOC libraries, where dependencies are requested through constructor parameters.
Simply add a new constructor to the class, and put the required components as parameters. Then, mark it with the [AutowireConstructor] attribute:
[Component] public ExecutableComponent { private NumbersService _numbers; [AutowireConstructor] internal ExecutableComponents(NumbersService numbers) { _numbers = numbers; } public void Run() { var result = _numbers.Sum(4, 5); } }
Keep in mind the following particularities of Autowired Constructors:
Request everything! All the time!
A component can use both Autowired Properties and Autowired Constructors to request all of its dependencies:
[Component] public class ExecutableComponent { private TimeService time; [Autowired] private NumbersService numbers; [AutowireConstructor] public ExecutableComponent(TimeService time) { this.time = time; } }
Refer to a component by its interface.
If a component has a type alias, you can request it both by the alias interface and its native type:
[Component] public class ExecutingComponent { // Alternative 1: Use type alias [Autowired] private INumbersService numbers; // Alternative 2: Use original type [Autowired] private NumbersService numbers; }
Note that this applies both to Autowired Properties and Autowired Constructors.