Fun facts about Snow components.
Components are the main building block in Snow. They can require and be injected into other components.
Generally speaking, any class that will make use of Snow, be it to request a dependency, to be injected as a dependency itself, or both must be tagged as a component. As an exception, the main class (which extends ISnowRunnable) can request dependencies without being a component (though it can be marked as such).
Components are defined by the use of the [Component] attribute, or other attribute that extends it. Snow provides the [Service] attribute as an example of this behavior. The difference between these attributes is only for added clarity to the users.
Let's add some functionality to the project.
Create a new class in your project. For organization purposes, we advise to put all component classes inside a folder, and name them with a Component or Service suffix. Of course, you can follow a different method.
Then, mark the class with the [Component] or [Service] attribute:
[Service] internal class NumbersService { }
Snow components don't have to be public classes. They can be internal or even private. The same applies to their methods, though you won't be able to call private methods unless you use reflection.
As components will be injected already instanced, static methods are unnecessary:
[Service] internal class NumbersService { internal int Sum(int a, int b) { return a + b; ] }
This class is now a valid component, and other components will be able to call the Sum() method. However, some components could require some initialization logic.
For this, you have two solutions: Either add a default constructor, or a static factory method marked with the [CreateInstance] attribute. Note that these two alternatives should not be combined.
[Service] internal class NumbersService { private int _factor; // Alternative 1: Default constructor public NumbersService() { _factor = 2; } // Alternative 2: Static factory method [CreateInstance] internal static NumbersService Initialize() { return new NumbersService { _factor = 2; } } internal int Multiply(int num) { return num * _factor; } }
It's possible for a component to have other components inside. It doesn't need any special work, simply request any needed dependencies as indicated in the 'Inject Components' tutorial.
Some remarks on components extending interfaces.
In the IOC world, it's very common to inject components as an interface instead of as a concrete type, for easier replacement of implementations.
Snow allows this in the form of 'Type Aliases', with the following limitations:
To indicate that a component has a type alias, use the [TypeAlias] attribute on it:
internal interface INumbersService { int Sum(int a, int b); } [Service] [TypeAlias(typeof(INumbersService)] internal class NumbersService : INumbersService { public int Sum(int a, int b) { return a + b; } }
Your project now has some components that will soon be injected as dependencies.