{ "cells": [ { "cell_type": "code", "execution_count": 28, "id": "20f77df0", "metadata": {}, "outputs": [], "source": [ "# Copyright (c) 2026 Microsoft Corporation.\n", "# Licensed under the MIT License." ] }, { "cell_type": "markdown", "id": "9305acf4", "metadata": {}, "source": [ "## Factory module example\n", "\n", "The Factory class provides a flexible dependency injection pattern that can register and create instances of classes implementing a common interface using string-based strategies. It supports both transient scope (creates new instances on each request) and singleton scope (returns the same instance after first creation)." ] }, { "cell_type": "code", "execution_count": 29, "id": "78777a9b", "metadata": {}, "outputs": [], "source": [ "from abc import ABC, abstractmethod\n", "\n", "from graphrag_common.factory import Factory\n", "\n", "\n", "class SampleABC(ABC):\n", " \"\"\"Abstract base class for sample implementations.\"\"\"\n", "\n", " @abstractmethod\n", " def get_value(self) -> str:\n", " \"\"\"Return the value of the sample implementation.\"\"\"\n", " msg = \"Subclasses must implement the get_value method.\"\n", " raise NotImplementedError(msg)\n", "\n", "\n", "class ConcreteClass(SampleABC):\n", " \"\"\"A concrete implementation of SampleABC.\"\"\"\n", "\n", " def __init__(self, value: str):\n", " print(f\"Creating ConcreteClass with value: {value}\")\n", " self._value = value\n", "\n", " def get_value(self) -> str:\n", " \"\"\"Return the value of the sample implementation.\"\"\"\n", " return self._value\n", "\n", "\n", "class SampleFactory(Factory[SampleABC]):\n", " \"\"\"A Factory for SampleABC classes.\"\"\"\n", "\n", "\n", "factory = SampleFactory()" ] }, { "cell_type": "code", "execution_count": 30, "id": "e11a9e01", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Creating ConcreteClass with value: test1\n", "Creating ConcreteClass with value: test2\n", "Value from trans1: test1\n", "Value from trans2: test2\n" ] } ], "source": [ "# Registering transient services\n", "# A new one is created for every request\n", "factory.register(\"some_strategy\", ConcreteClass)\n", "\n", "trans1 = factory.create(\"some_strategy\", {\"value\": \"test1\"})\n", "trans2 = factory.create(\"some_strategy\", {\"value\": \"test2\"})\n", "\n", "print(f\"Value from trans1: {trans1.get_value()}\") # Output: test1\n", "print(f\"Value from trans2: {trans2.get_value()}\") # Output: test2\n", "\n", "assert trans1 is not trans2\n", "assert trans1.get_value() == \"test1\"\n", "assert trans2.get_value() == \"test2\"" ] }, { "cell_type": "code", "execution_count": 31, "id": "45e9ed13", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Creating ConcreteClass with value: singleton\n", "Creating ConcreteClass with value: ignored\n", "Value from single1: singleton\n", "Value from single2: ignored\n" ] } ], "source": [ "# Registering singleton services\n", "# After first creation, the same one is returned every time\n", "factory.register(\"some_other_strategy\", ConcreteClass, scope=\"singleton\")\n", "\n", "single1 = factory.create(\"some_other_strategy\", {\"value\": \"singleton\"})\n", "single2 = factory.create(\"some_other_strategy\", {\"value\": \"ignored\"})\n", "\n", "print(f\"Value from single1: {single1.get_value()}\") # Output: singleton\n", "print(f\"Value from single2: {single2.get_value()}\") # Output: singleton\n", "\n", "assert single1 is not single2\n", "assert single1.get_value() == \"singleton\"\n", "assert single2.get_value() == \"ignored\"" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.9" } }, "nbformat": 4, "nbformat_minor": 5 }