Building further upon what you already know and have.
Since there's no public access to the cache keys set up by the OutputCacheAttribute - it's all internal and private, see source code at GitHub - we can't clear the cache via those ones.
As suggested and without too much rework of your current setup, you can make use of a separate OutputCacheProvider per domain.
To indicate the OutputCacheProvider that should be used for a request you need to override GetOutputCacheProviderName in global.asax.cs.
The below example matches the logic you already have.
public override string GetOutputCacheProviderName(HttpContext context)
{
return HttpContext.Current.Request.Url.Host.Equals(
"frenchwebsite.com", StringComparison.OrdinalIgnoreCase
) ? "fr" : "en";
}
Both named providers (and the default one) must be configured in web.config, specifying its type (namespace + class and assembly).
In this simplified example, the en one is also the default.
<configuration>
<system.web>
<caching>
<outputCache defaultProvider="en" enableOutputCache="true">
<providers>
<add name="en"
type="MyWebApp.Caching.CustomOutputCacheProvider, MyWebApp" />
<add name="fr"
type="MyWebApp.Caching.CustomOutputCacheProvider, MyWebApp" />
</providers>
</outputCache>
</caching>
<!-- Other settings ... -->
</system.web>
<!-- Other settings ... -->
<configuration>
The above custom MyWebApp.Caching.CustomOutputCacheProvider - see code below - is a very basic one that just uses the Cache of ASP.NET.
Since the same single (by default memory) cache is being used for both the en and fr content, the cache keys are being prefixed with the provider name.
Note that this is rather a proof of concept implementation, which you might need to fine-tune. A minimal test run showed that this can work.
namespace MyWebApp.Caching
{
public class CustomOutputCacheProvider : OutputCacheProvider
{
public override object Add(string key, object entry, DateTime utcExpiry)
{
return HttpRuntime.Cache.Add(
NormalizeKey(key), entry, null, utcExpiry, TimeSpan.Zero, CacheItemPriority.Normal, null
);
}
public override object Get(string key)
{
return HttpRuntime.Cache.Get(NormalizeKey(key));
}
public override void Remove(string key)
{
HttpRuntime.Cache.Remove(NormalizeKey(key));
}
public override void Set(string key, object entry, DateTime utcExpiry)
{
HttpRuntime.Cache.Insert(
NormalizeKey(key), entry, null, utcExpiry, TimeSpan.Zero
);
}
private string NormalizeKey(string key)
{
return $"{Name}::{key}";
}
}
}
As there will be a separate cache per domain (via the prefixed cache keys), the VaryByCustom = "domain" can be omitted from the OutputCacheAttribute; just use e.g.
[OutputCache(Location = OutputCacheLocation.Server, Duration = 60)]
You can of course apply a VaryByCustom for any other distinction you need to make.
In order to clear e.g. the en content of the home page, you pass the name of the corresponding provider as 2nd argument to the RemoveOutputCachItem method.
Response.RemoveOutputCacheItem("/", "en");
Alternatively you might set up a caching strategy yourself with well known and predicatable cache keys being used to both insert into and remove from the cache. But that looks like too much for what you ask for.