Comprehensive In-Memory Caching (fix #404)
How It Works
Fix this
When you call new ArchLoader().LoadAssemblies(...).Build(), ArchUnitNET automatically:
- Creates a cache key based on the modules being loaded and any namespace filters applied
- Checks the cache for a previously loaded Architecture instance matching this key
- Returns the cached instance if found, or loads and caches a new instance if not
This means that loading the same assemblies multiple times (even with different ArchLoader instances) will reuse the cached Architecture object, providing dramatic performance improvements.
Usage Examples
Basic usage (automatic caching with file-based invalidation):
var arch = new ArchLoader()
.LoadAssemblies(assembly)
.Build(); // Automatically cached with invalidation
Custom cache key for test isolation:
var arch = new ArchLoader()
.WithUserCacheKey("test-run-1")
.LoadAssemblies(assembly)
.Build();
Disable caching for specific scenarios:
var arch = new ArchLoader()
.WithoutCaching()
.LoadAssemblies(assembly)
.Build();
Advanced configuration (config is cloned internally):
var config = new ArchLoaderCacheConfig
{
CachingEnabled = true,
UseFileBasedInvalidation = true, // Check file changes
UserCacheKey = "integration-tests",
IncludeVersionInCacheKey = true // Invalidate on version change
};
var arch = new ArchLoader()
.WithCacheConfig(config)
.LoadAssemblies(assembly)
.Build();
// Safe: modifying config after passing it won't affect the ArchLoader
config.UserCacheKey = "different-key";
@alexanderlinne Could you review this, please?
We’re also experiencing very slow performance with large projects — when there are many files, it becomes extremely slow and can take up to 15 minutes to complete. Hopefully, this merge will address the issue.
Hi @mokarchi,
what you've implemented here, as far as I see, is in principle already covered by ArchitectureCache. So if you load the exact same architecture with exact same assemblies twice within the same test run, the Architecture should already be reused. I don't see what justifies second implementation of the same functionality here. Could you explain what the exact additional functionality provided here is?
I'd see the addition of WithoutCaching as a solution for #399 and we could improve the ArchitectureCacheKey if there were cases in which it is not unique. But this could as well be implemented with the existing cache implementation.
Performance-wise I'd expect the biggest improvement could probably be achieved by moving some work that is currently done when calling LoadAssemblies into the build method after the existing architecture cache check.