InjectionDemo.vala 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. using Inversion;
  2. /**
  3. * Injection Demo Example
  4. *
  5. * This example demonstrates the inject<T>() method for property/field injection.
  6. * The inject method allows dependencies to be resolved during object construction
  7. * without requiring explicit constructor parameters.
  8. *
  9. * Key concepts:
  10. * - Using inject<T>() for field initialization
  11. * - The injection context is automatically set up during container resolution
  12. * - Multiple dependencies can be injected in the same class
  13. */
  14. public class InjectionDemoExample : Object {
  15. // Define service interfaces
  16. public interface IHandler : Object {
  17. public abstract void handle(string request);
  18. }
  19. public interface IRepository : Object {
  20. public abstract string get_data();
  21. }
  22. // Console handler implementation
  23. public class ConsoleHandler : Object, IHandler {
  24. public void handle(string request) {
  25. stdout.printf("[HANDLER] Processing: %s\n", request);
  26. }
  27. }
  28. // Memory repository implementation
  29. public class MemoryRepository : Object, IRepository {
  30. public string get_data() {
  31. return "Sample data from repository";
  32. }
  33. }
  34. // A service that uses inject<T>() for dependency injection
  35. // This class demonstrates field injection using the inject method
  36. public class Controller : Object {
  37. // Dependencies are injected during object construction
  38. private IHandler handler = inject<IHandler>();
  39. private IRepository repository = inject<IRepository>();
  40. public void process_request(string request) {
  41. var data = this.repository.get_data();
  42. stdout.printf("[CONTROLLER] Retrieved data: %s\n", data);
  43. this.handler.handle(request);
  44. }
  45. }
  46. // Another service demonstrating nested injection
  47. public class ApiService : Object {
  48. private Controller controller = inject<Controller>();
  49. public void execute(string request) {
  50. stdout.printf("[API] Executing request: %s\n", request);
  51. this.controller.process_request(request);
  52. }
  53. }
  54. public static int main(string[] args) {
  55. stdout.printf("=== Inversion IoC Injection Demo ===\n\n");
  56. // Create the container
  57. var container = new Container();
  58. // Register all services with factory delegates
  59. container.register_singleton<ConsoleHandler>((scope) => new ConsoleHandler())
  60. .as_type(typeof(IHandler));
  61. container.register_singleton<MemoryRepository>((scope) => new MemoryRepository())
  62. .as_type(typeof(IRepository));
  63. // Register Controller - it will use inject<T>() to resolve its dependencies
  64. container.register_scoped<Controller>((scope) => new Controller());
  65. // Register ApiService - demonstrates nested injection
  66. container.register_transient<ApiService>((scope) => new ApiService());
  67. stdout.printf("Registered services:\n");
  68. stdout.printf(" - ConsoleHandler as IHandler (Singleton)\n");
  69. stdout.printf(" - MemoryRepository as IRepository (Singleton)\n");
  70. stdout.printf(" - Controller (Scoped) - uses inject<T>()\n");
  71. stdout.printf(" - ApiService (Transient) - uses inject<T>()\n\n");
  72. // Create a scope
  73. var scope = container.create_scope();
  74. try {
  75. stdout.printf("--- Resolving ApiService (demonstrates nested injection) ---\n\n");
  76. // Resolve ApiService - this will trigger:
  77. // 1. ApiService construction -> inject<Controller>()
  78. // 2. Controller construction -> inject<IHandler>() and inject<IRepository>()
  79. var api_service = scope.resolve<ApiService>();
  80. api_service.execute("Test request #1");
  81. stdout.printf("\n--- Resolving Controller directly ---\n\n");
  82. // Resolve Controller directly
  83. var controller = scope.resolve<Controller>();
  84. controller.process_request("Test request #2");
  85. // Verify scoped behavior - same controller instance within scope
  86. var controller2 = scope.resolve<Controller>();
  87. if (controller == controller2) {
  88. stdout.printf("\n✓ Scoped working: Same Controller instance within scope\n");
  89. }
  90. stdout.printf("\n--- Creating another scope ---\n\n");
  91. // Create another scope - should get a new Controller instance
  92. var scope2 = container.create_scope();
  93. var controller_in_scope2 = scope2.resolve<Controller>();
  94. controller_in_scope2.process_request("Test request #3");
  95. if (controller != controller_in_scope2) {
  96. stdout.printf("\n✓ Scoped working: Different Controller instance in different scope\n");
  97. }
  98. } catch (Error e) {
  99. stderr.printf("Error: %s\n", e.message);
  100. return 1;
  101. }
  102. stdout.printf("\n=== Example Complete ===\n");
  103. return 0;
  104. }
  105. }