{"id":22549053,"url":"https://github.com/dcfapixels/dragonecs-autoinjections","last_synced_at":"2025-04-10T01:52:51.602Z","repository":{"id":171110156,"uuid":"620721955","full_name":"DCFApixels/DragonECS-AutoInjections","owner":"DCFApixels","description":"Automatic dependency injections for DragonECS","archived":false,"fork":false,"pushed_at":"2025-03-17T03:07:13.000Z","size":121,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-24T03:34:52.647Z","etag":null,"topics":["dragon-ecs","dragonecs","extension"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DCFApixels.png","metadata":{"files":{"readme":"README-RU.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-29T08:43:35.000Z","updated_at":"2025-03-15T09:14:43.000Z","dependencies_parsed_at":null,"dependency_job_id":"f21a8850-6292-459a-9f36-3447bd51ed56","html_url":"https://github.com/DCFApixels/DragonECS-AutoInjections","commit_stats":null,"previous_names":["dcfapixels/dragonecs-autoinjections"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DCFApixels%2FDragonECS-AutoInjections","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DCFApixels%2FDragonECS-AutoInjections/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DCFApixels%2FDragonECS-AutoInjections/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DCFApixels%2FDragonECS-AutoInjections/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DCFApixels","download_url":"https://codeload.github.com/DCFApixels/DragonECS-AutoInjections/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248142940,"owners_count":21054671,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dragon-ecs","dragonecs","extension"],"created_at":"2024-12-07T16:07:45.530Z","updated_at":"2025-04-10T01:52:51.581Z","avatar_url":"https://github.com/DCFApixels.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\u003cimg width=\"400\" src=\"https://github.com/DCFApixels/DragonECS-AutoInjections/assets/99481254/11868b2e-21f7-4f47-8970-03ad6329cf0e\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003cimg alt=\"Version\" src=\"https://img.shields.io/github/package-json/v/DCFApixels/DragonECS-AutoInjections?color=%23ff4e85\u0026style=for-the-badge\"\u003e\n\u003cimg alt=\"License\" src=\"https://img.shields.io/github/license/DCFApixels/DragonECS-AutoInjections?color=ff4e85\u0026style=for-the-badge\"\u003e\n\u003ca href=\"https://discord.gg/kqmJjExuCf\"\u003e\u003cimg alt=\"Discord\" src=\"https://img.shields.io/badge/Discord-JOIN-00b269?logo=discord\u0026logoColor=%23ffffff\u0026style=for-the-badge\"\u003e\u003c/a\u003e\n\u003ca href=\"http://qm.qq.com/cgi-bin/qm/qr?_wv=1027\u0026k=IbDcH43vhfArb30luGMP1TMXB3GCHzxm\u0026authKey=s%2FJfqvv46PswFq68irnGhkLrMR6y9tf%2FUn2mogYizSOGiS%2BmB%2B8Ar9I%2Fnr%2Bs4oS%2B\u0026noverify=0\u0026group_code=949562781\"\u003e\u003cimg alt=\"QQ\" src=\"https://img.shields.io/badge/QQ-JOIN-00b269?logo=tencentqq\u0026logoColor=%23ffffff\u0026style=for-the-badge\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n# Auto Injections for [DragonECS](https://github.com/DCFApixels/DragonECS)\n\n\u003ctable\u003e\n  \u003ctr\u003e\u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd colspan=\"3\"\u003eReadme Languages:\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd nowrap width=\"100\"\u003e\n      \u003ca href=\"https://github.com/DCFApixels/DragonECS-AutoInjections/blob/main/README-RU.md\"\u003e\n        \u003cimg src=\"https://github.com/user-attachments/assets/3c699094-f8e6-471d-a7c1-6d2e9530e721\"\u003e\u003c/br\u003e\n        \u003cspan\u003eРусский\u003c/span\u003e\n      \u003c/a\u003e  \n    \u003c/td\u003e\n    \u003ctd nowrap width=\"100\"\u003e\n      \u003ca href=\"https://github.com/DCFApixels/DragonECS-AutoInjections\"\u003e\n        \u003cimg src=\"https://github.com/user-attachments/assets/30528cb5-f38e-49f0-b23e-d001844ae930\"\u003e\u003c/br\u003e\n        \u003cspan\u003eEnglish(WIP)\u003c/span\u003e\n      \u003c/a\u003e  \n    \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\u003c/br\u003e\n\nРасширение призвано сократить объем кода, упростив инъекцию  зависимостей, делая их автоматически.\n\n\u003e [!WARNING] \n\u003e Проект в стадии разработки. API может меняться.\n\n# Оглавление\n- [Установка](#установка)\n- [Интеграция](#интеграция)\n- [Инъекция зависимостей](#инъекция-зависимостей)\n- [Auto Builder аспектов](#auto-builder-аспектов)\n- [Auto Runner-ы](#auto-runner-ы)\n- [Пример кода](#пример-кода)\n- [Не null инъекции](#не-null-инъекции)\n\n\u003c/br\u003e\n\n# Установка\nСемантика версионирования - [Открыть](https://gist.github.com/DCFApixels/e53281d4628b19fe5278f3e77a7da9e8#file-dcfapixels_versioning_ru-md)\n## Окружение\nОбязательные требования:\n+ Зависимость: [DragonECS](https://github.com/DCFApixels/DragonECS)\n+ Минимальная версия C# 7.3;\n\nОпционально:\n+ Игровые движки с C#: Unity, Godot, MonoGame и т.д.\n\nПротестировано:\n+ **Unity:** Минимальная версия 2020.1.0;\n\n## Установка для Unity\n* ### Unity-модуль\nПоддерживается установка в виде Unity-модуля в  при помощи добавления git-URL [в PackageManager](https://docs.unity3d.com/2023.2/Documentation/Manual/upm-ui-giturl.html) или ручного добавления в `Packages/manifest.json`: \n```\nhttps://github.com/DCFApixels/DragonECS-AutoInjections.git\n```\n* ### В виде исходников\nФреймворк так же может быть добавлен в проект в виде исходников.\n\n\u003c/br\u003e\n\n# Интеграция\nДобавьте вызов метода `AutoInject()` для Builder-а пайплайна. Пример:\n```csharp\n_pipeline = EcsPipeline.New()\n    .Inject(world)\n    .Inject(_timeService)\n    .Add(new TestSystem())\n    .Add(new VelocitySystem())\n    .Add(new ViewSystem())\n    .AutoInject() // Готово, автоматические внедрения активированы\n    .BuildAndInit();\n```\n\n\u003c/br\u003e\n\n# Инъекция зависимостей\nАтрибут `[EcsInject]` убирает необходимость использования интерфейса `IEcsInject\u003cT\u003e`, поля помеченные таким атрибутом автоматически подхватят зависимости внедренные в Pipeline. Пример： \n```csharp\n[EcsInject] EcsDefaultWorld _world;\n```\nТак же можно делать внедрение через свойство или метод:\n```csharp\nEcsDefaultWorld _world;\n\n//Обязательно наличие set блока.  \n[EcsInject] EcsDefaultWorld World { set =\u003e _world = value; } \n\n//Количество аргументов должно быть равно 1.\n[EcsInject] void InjectWorld(EcsDefaultWorld world) =\u003e _world = world;\n```\n\n\u003e Поддерживается агрессивная инъекция, инъекция будет произведена без атрибута `[EcsInject]`, для этого нужно вызвать `.AutoInject(true)`.\n\n\u003c/br\u003e\n\n# Auto Builder аспектов\nТак же AutoInjections упрощает построение аспектов. Для начала наследуйте аспект не от `EcsAspect`, а от `EcsAspectAuto`, а далее добавьте специальные атрибуты.\n\nАтрибуты для инициализации полей с пулами: \n* `[Inc]` - кеширует пул и добавит тип компонента в включающее ограничение аспекта, аналог метода `Include`;\n* `[Exc]` - кеширует пул и добавит тип компонента в исключающее ограничение аспекта, аналог метода `Exclude`;\n* `[Opt]` - только кеширует пул, аналог метода `Optional`;\n\nАтрибут для комбинирования аспектов:\n* `[Combine(order)]` - кеширует аспект и скомбинирует ограничения аспектов, аналог метода `Combine`, аргумент `order` задает порядок комбинирования, по умлочанию `order = 0`;\n\nДополнительные атрибуты только для задания ограничений аспекта. Их можно применить к самому аспекту, либо к любому полю внутри. Используйте атрибуты: \n* `[IncImplicit(type)]` - добавит в включающее ограничение указанный в конструкторе тип `type`, аналог метода `Include`;\n* `[ExcImplicit(type)]` - добавит в исключающее ограничение указанный в конструкторе тип `type`, аналог метода `Exclude`;\n\n\u003c/br\u003e\n\n# Auto Runner-ы\nДля получения раннеров без добавления, есть атрибут `[BindWithRunner(type)]` и метод `GetRunnerAuto\u003cT\u003e()`. \n``` c#\n[BindWithRunner(typeof(DoSomethingProcessRunner))]\ninterface IDoSomethingProcess : IEcsProcess\n{\n    void Do();\n}\n//Реализация раннера. Пример реализации можно так же посмотреть в встроенных процессах \nsealed class DoSomethingProcessRunner : EcsRunner\u003cIDoSomethingProcess\u003e, IDoSomethingProcess\n{\n    public void Do() \n    {\n        foreach (var item in Process) item.Do();\n    }\n}\n\n//...\n// Если в пайплайн не был добавлен раннер, то GetRunnerAuto автоматически добавит экземпляр DoSomethingProcessRunner.\n_pipeline.GetRunnerAuto\u003cIDoSomethingProcess\u003e().Do();\n```\n\n\u003c/br\u003e\n\n# Пример кода\n```csharp\nclass VelocitySystemDI : IEcsRun\n{\n    class Aspect : EcsAspectAuto\n    {\n        [ExcImplicit(typeof(FreezedTag))]\n        [Inc] public EcsPool\u003cPose\u003e poses;\n        [Inc] public EcsPool\u003cVelocity\u003e velocities;\n    }\n\n    [EcsInject] EcsDefaultWorld _world;\n    [EcsInject] TimeService _time;\n\n    public void Run()\n    {\n        foreach (var e in _world.Where(out Aspect a))\n        {\n            a.poses.Get(e).position += a.velocities.Read(e).value * _time.DeltaTime;\n        }\n    }\n}\n```\n\u003cdetails\u003e\n\u003csummary\u003eТот же код но без AutoInjections\u003c/summary\u003e\n    \n```csharp\nclass VelocitySystem : IEcsRun, IEcsInject\u003cEcsDefaultWorld\u003e, IEcsInject\u003cTimeService\u003e\n{\n    class Aspect : EcsAspect\n    {\n        public EcsPool\u003cPose\u003e poses;\n        public EcsPool\u003cVelocity\u003e velocities;\n        public Aspect(Builder b)\n        {\n            b.Exclude\u003cFreezedTag\u003e();\n            poses = b.Include\u003cPose\u003e();\n            velocities = b.Include\u003cVelocity\u003e();\n        }\n    }\n\n    EcsDefaultWorld _world;\n    TimeService _time;\n\n    public void Inject(EcsDefaultWorld obj) =\u003e _world = obj;\n    public void Inject(TimeService obj) =\u003e _time = obj;\n\n    public void Run()\n    {\n        foreach (var e in _world.Where(out Aspect a))\n        {\n            a.poses.Get(e).position += a.velocities.Read(e).value * _time.DeltaTime;\n        }\n    }\n}\n```\n\n\u003c/details\u003e\n    \n\u003c/br\u003e\n\n# Не null инъекции\n\nЧтобы поле помеченное `[EcsInject]` было проинициализированно даже в случае отстувия инъекции, в конструктор атрибута можно передать тип болванку. В примере ниже поле `foo` получит экземпляр класса `Foo` из инъекции или экземпляр `FooDummy : Foo` если инъекции не было.\n``` csharp\n[EcsInject(typeof(FooDummy))] Foo foo;\n```\n\u003e Переданный тип должен иметь конструктор без параметров и быть либо того же типа что и тип поля, либо производного типа. \n  \nРасширение так же сообщит если по завершению предварительной инъекции, остались не проинициализированные поля с `[EcsInject]`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdcfapixels%2Fdragonecs-autoinjections","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdcfapixels%2Fdragonecs-autoinjections","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdcfapixels%2Fdragonecs-autoinjections/lists"}