{"id":17197213,"url":"https://github.com/thomaslevesque/lazyproxy","last_synced_at":"2025-03-25T08:28:46.630Z","repository":{"id":36382195,"uuid":"40687069","full_name":"thomaslevesque/LazyProxy","owner":"thomaslevesque","description":"Dynamic lazy proxy to allow injection of circular dependencies","archived":false,"fork":false,"pushed_at":"2015-08-30T03:06:42.000Z","size":156,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-30T07:43:21.070Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thomaslevesque.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-13T23:58:08.000Z","updated_at":"2015-08-13T23:58:54.000Z","dependencies_parsed_at":"2022-09-09T11:52:13.223Z","dependency_job_id":null,"html_url":"https://github.com/thomaslevesque/LazyProxy","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomaslevesque%2FLazyProxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomaslevesque%2FLazyProxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomaslevesque%2FLazyProxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomaslevesque%2FLazyProxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thomaslevesque","download_url":"https://codeload.github.com/thomaslevesque/LazyProxy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245425528,"owners_count":20613182,"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":[],"created_at":"2024-10-15T01:55:48.748Z","updated_at":"2025-03-25T08:28:46.609Z","avatar_url":"https://github.com/thomaslevesque.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LazyProxy\n\nDynamic lazy proxy to allow injection of circular dependencies, either with or without an IoC container.\n\n*Note: at this point, this library is just a POC, not production ready code. Only the most basic cases are covered. Things like events, generic methods, and ref/out parameters are not supported.*\n\nAssume you have two interfaces like this:\n\n    public interface IFoo\n    {\n        void Test();\n        int X { get; }\n    }\n    \n    public interface IBar\n    {\n        string Baz();\n    }\n\nAnd the implementation of each interface depends on the other interface:\n\n    class Foo : IFoo\n    {\n        private readonly IBar _bar;\n        public Foo(IBar bar)\n        {\n            _bar = bar;\n        }\n        \n        public void Test() =\u003e Console.WriteLine(_bar.Baz());\n        public int X =\u003e 42;\n    }\n    \n    class Bar : IBar\n    {\n        private IFoo _foo;\n        public Bar(IFoo foo)\n        {\n            _foo = foo;\n        }\n    \n        public string Baz() =\u003e $\"The answer is {_foo.X}\";\n    }\n\nWe have a circular dependency: `Foo` depends on `IBar`, which is implemented by `Bar`, which depends on `IFoo`,\nwhich is implemented by `Foo`. In theory, there is no way to perform this injection, since we need `Foo` to create\n`Bar`, and vice versa... it's a chicken and egg problem. But there's a trick that would let us do it anyway: we just\nneed to resolve either `Foo` or `Bar` lazily. Instead of injecting `Bar` directly as the implementation of `IBar`, we could\ninject a proxy class like this:\n\n    class IBar_LazyProxy : IBar\n    {\n        private Lazy\u003cBar\u003e _lazy;\n        public IBar_LazyProxy(Lazy\u003cBar\u003e lazy)\n        {\n            _lazy = lazy;\n        }\n    \n        public string Baz() =\u003e _lazy.Value.Baz();\n    }\n    \nThis class just delegates the implementation to a lazily resolved instance of `Bar`. Since it doesn't depend on `IFoo`,\nthere is no circular dependency. Only the first time `Baz()` is called, the actual instance of `Bar` will be resolved,\nand the resolution will work because `Foo` will already have been resolved.\n\nBut writing such a proxy class manually is tedious; so this library generates it dynamically at runtime. It provides\nextension methods to register lazy types in a Unity container. In the example above, the container could be configured\nlike this:\n\n    var container = new UnityContainer();\n    container.RegisterType\u003cIFoo, Foo\u003e();\n    container.RegisterLazy\u003cIBar, Bar\u003e();\n\n    var foo = container.Resolve\u003cIFoo\u003e();\n    foo.Test();\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomaslevesque%2Flazyproxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthomaslevesque%2Flazyproxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomaslevesque%2Flazyproxy/lists"}