Contracts
Pre-defined contracts included with uMod
Introduction
uMod makes heavy use of contract abstractions and interfaces. Plugin developers commonly need to declare interfaces or contract abstractions for configuration, data models, file schematics, or integrating plugins.
Commonly used interfaces such as IPlayer or IPlugin declare properties and methods that might be used to interact with players or integrate with other plugins.
Each interface has a corresponding implementation within the core, platform extensions, or game extensions.
Why use interfaces?
Explicitly defining and implementing interfaces at key integration points will result in code that is more flexible, extensible, readable, and maintainable.
Extendable core
By using contract interfaces, it is easier for functionality to be extended or overridden. For example, the ILogger interface is implemented many times.
Developers can make the assumption that any given logger has a minimum implementation and functions in a similar way because every logger must implement the contract defined in the ILogger interface.
By reducing core functionality to a minimum set of interfaces uMod can support mock environments to run hundreds of unit tests to ensure the long-term stability of uMod and uMod plugins.
Loose coupling
Components will have few dependencies and be largely independent from other components when implemented with SOLID design principles.
Loosely coupled components that are SOLID and coded against interfaces can easily be exchanged with alternative implementations that implement the same interface. Allowing alternative implementations to be exchanged reduces code duplication and increases testability and flexibility. Further, making a change to a single component is less likely to impact other surrounding components.
public interface ILogger
{
LogLevel LogLevel { get; }
void Write(LogLevel level, string message);
}
For example, the core implements a wide variety of such loggers, each with the explicitly defined minimum implementation above.