{"id":16473097,"url":"https://github.com/binki/ohnopub.mefcacher","last_synced_at":"2026-05-17T03:36:49.687Z","repository":{"id":143134250,"uuid":"64044358","full_name":"binki/OhNoPub.MefCacher","owner":"binki","description":"A hacked-together MEF ComposablePartCatalog caching layer","archived":false,"fork":false,"pushed_at":"2017-03-11T16:55:49.000Z","size":41,"stargazers_count":1,"open_issues_count":3,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-28T12:40:37.723Z","etag":null,"topics":["composition","dotnet","mef"],"latest_commit_sha":null,"homepage":null,"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/binki.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING.md","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":"2016-07-24T02:08:15.000Z","updated_at":"2017-06-07T13:54:41.000Z","dependencies_parsed_at":"2023-04-10T08:33:57.531Z","dependency_job_id":null,"html_url":"https://github.com/binki/OhNoPub.MefCacher","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/binki/OhNoPub.MefCacher","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binki%2FOhNoPub.MefCacher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binki%2FOhNoPub.MefCacher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binki%2FOhNoPub.MefCacher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binki%2FOhNoPub.MefCacher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/binki","download_url":"https://codeload.github.com/binki/OhNoPub.MefCacher/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/binki%2FOhNoPub.MefCacher/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272878320,"owners_count":25008336,"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","status":"online","status_checked_at":"2025-08-30T02:00:09.474Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["composition","dotnet","mef"],"created_at":"2024-10-11T12:25:19.421Z","updated_at":"2025-10-29T10:23:12.848Z","avatar_url":"https://github.com/binki.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build status](https://ci.appveyor.com/api/projects/status/fcqvbm756p7ojhy0?svg=true)](https://ci.appveyor.com/project/binki/ohnopub-mefcacher)\r\n\r\nThere are two goals to this project:\r\n\r\n1. Enable the most general and declarative MEF usage pattern (i.e., using [`ApplicationCatalog`](https://msdn.microsoft.com/en-us/library/system.componentmodel.composition.hosting.applicationcatalog%28v=vs.110%29.aspx)).\r\n   When buying into a composition pattern, it is really nice to let the system follow a well-established and accepted set of conventions to orchestrate parts.\r\n   Writing your own initialization code to reduce startup delays means ignoring these conventions/patterns and ends up mixing concerns and defeating the whole point of a composition pattern.\r\n\r\n2. Enable fast startup and initial composition.\r\n   For MEF to compose a part with any imports, it needs to scan the entire catalog for parts to verify that the cardinality of the import is being respected.\r\n   This defeats the framework痴 optimization of lazily loading assemblies and causes a noticable and unacceptable slowdown in program initialization, especially when allowing all assemblies in an application to contribute parts.\r\n\r\nMEF痴 catalogs allow a separation between a part instance and its definition.\r\nIt should be possible to just feed MEF the part definitions necessary for it to validate cardinality constraints and decide which parts actually need to be activated.\r\nThis way, assembly loading can be deferred using a lazy pattern until parts are actually needed in a manner similar to how .net lazily loads assemblies.\r\nIf this is done, initial composition can be made responsive while still allowing a general catalog without need for manual tuning/specialization.\r\n\r\nThe design of `CachingCatalog` supports automatic cache rebuilding and initialization.\r\nThe idea is that you can detect that a particular assembly has changed without fully loading it用erhaps using filesystem-provided metadata such as mtime.\r\nDuring normal application use, the assembly would be stable.\r\nThus, the program would build the cache on the first run and use it in subsequent runs.\r\nOr perhaps the cache can be prepopulated before distribution of the program.\r\n\r\nBecause of the nature of the caching pattern, it is best if the cache can be assembly-aware.\r\nThus, imitations of `DirectoryCatalog` and `ApplicationCatalog` called `DirectoryCachingCatalog` and `ApplicationCachingCatalog` are provided.\r\nThe pattern I personally recommend is:\r\n\r\n    using OhNoPub.MefCacher;\r\n    using System.ComponentModel;\r\n    using System.ComponentModel.Composition.Hosting;\r\n    \r\n    [Export]\r\n    public class Program\r\n    {\r\n        [Import]\r\n        public Whatever Whatever { get; set; }\r\n        \r\n        static int Main(string[] args)\r\n        {\r\n            using (var catalog = new ApplicationCachingCatalog())\r\n            {\r\n                using (var container = new CompositionContainer(catalog))\r\n                {\r\n                    return catalog.GetExportedValue\u003cProgram\u003e().Run(args);\r\n                }\r\n            }\r\n        }\r\n\r\n        int Run(string[] args)\r\n        {\r\n            Whatever.DoSomething();\r\n            return 0;\r\n        }\r\n    }\r\n\r\nAnd… that is the vision.\r\nIt does not work quite so far yet.\r\nThis repository however has a few test cases and some of the necessary scaffolding to support the future API.\r\nIt might even almost be to the point of being interesting.\r\nThus I’m sharing it ^^.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinki%2Fohnopub.mefcacher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbinki%2Fohnopub.mefcacher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinki%2Fohnopub.mefcacher/lists"}