This is a problem recently encountered in real development, using ASP. NET core to develop a back-end Web API that clears the cache on 2 memcached servers based on the specified key. The background is that we are working on. NET core migrations, where the ASP is co-existing with the ASP. To avoid caching conflicts between the two types of projects, we used 2 different memcached servers respectively.
Before using 1 memcached servers, only one client was needed, so just create a single memcachedclient and inject it into the Imemcachedclient interface.
Public void configureservices (iservicecollection services) { services. AddOptions (); Services. Configure<MemcachedClientOptions> (configuration.getsection ("memcached" )); Services. ADD (servicedescriptor.transient<imemcachedclientconfiguration, memcachedclientconfiguration>()) ; Services. ADD (Servicedescriptor.singleton<imemcachedclient, memcachedclient>());}
(Note: The configuration of memcached is stored in Appsettings.json)
Now you need to connect 2 different memcached servers with 2 memcached client instances, requiring 2 different configurations of Memcachedclient Singleton, and the previous dependency injection method for 1 imemcachedclient interfaces does not work The What's the whole?
The first thought is a workaround, 1 interface does not, then use 2 interfaces, so add the following 2 interfaces:
Public Interface imemcachedclientcore:imemcachedclient{
}publicinterface imemcachedclientlegacy:imemcachedclient{
}
Because Memcachedclient does not implement these 2 interfaces, there are additional implementations of these 2 interfaces:
Public classmemcachedclientcore:memcachedclient, imemcachedclientcore{ PublicMemcachedclientcore (ILogger<MemcachedClient>logger, imemcachedclientconfiguration configuration):Base(logger, configuration) {}} Public classmemcachedclientlegacy:memcachedclient, imemcachedclientlegacy{ Publicmemcachedclientlegacy (ILogger<MemcachedClient>logger, imemcachedclientconfiguration configuration):Base(logger, configuration) {}}
Along the way, we find that the farther and the worse, the more interfaces and implementations are added. Since the difference between the 2 memcached clients is imemcachedclientconfiguration, the above Memcachedclientcore and memcachedclientlegacy constructors inject IM Emcachedclientconfiguration is not possible, but also based on the imemcachedclientconfiguration to add 2 additional interfaces, adding the interface will have to increase the implementation ... It is not madness to solve the problem and abandon it.
Later on, I thought that my own problem-solving thinking went off, blindly focused on how to inject 2 different memcachedclient instances through Dependency injection, ignoring a very simple solution--Create with factory class Memcachedclient instances are injected into the factory class through Dependency injection, just like iloggerfactory.
This problem was easily solved by a factory model based on dependency injection.
Define a Imemcachedclientfactory interface:
Public Interface { imemcachedclientfactory Add (string keyofconfiguration); Imemcachedclient Create (string keyofconfiguration); }
Add the Memcachedclientfactory class to implement the Imemcachedclientfactory interface:
Public classmemcachedclientfactory:imemcachedclientfactory{Private ReadOnlyiloggerfactory _loggerfacotry; Private ReadOnlyiconfiguration _configuration; Private ReadOnlydictionary<string, imemcachedclient> _clients =Newdictionary<string, imemcachedclient>(); Publicmemcachedclientfactory (iloggerfactory loggerfacotry, iconfiguration configuration) {_logger Facotry=Loggerfacotry; _configuration=configuration; } PublicImemcachedclientfactory Add (stringkeyofconfiguration) { varOptions =Newmemcachedclientoptions (); _configuration. GetSection (keyofconfiguration). Bind (options); varMemcachedclient =Newmemcachedclient (_loggerfacotry,Newmemcachedclientconfiguration (_loggerfacotry, Options)); _clients. ADD (Keyofconfiguration, memcachedclient); return This; } PublicImemcachedclient Create (stringkeyofconfiguration) { return_clients[keyofconfiguration]; }}
A single example of injecting memcachedclientfactory in Startup.configureservices ():
Public void configureservices (iservicecollection services) { services. Addsingleton<imemcachedclientfactory, memcachedclientfactory>();}
In Startup.configure (), call the Add () method of the Imemcachedclientfactory interface to create an instance of Memcachedclient based on a different configuration:
Public void Configure (Iapplicationbuilder app, Imemcachedclientfactory memcachedclientfactory) { Memcachedclientfactory.add ("memcachedlegacy"). ADD ("memcachedcore");}
Get an instance of the desired memcachedclient by using the Create () method of the Imemcachedclientfactory interface where memcachedclient is used:
Public classcachecontroller:controller{Private ReadOnlyimemcachedclient _memcachedclientlegacy; Private ReadOnlyimemcachedclient _memcachedclientcore; PublicCachecontroller (imemcachedclientfactory memcachedclientfacotry) {_memcachedclientlegacy= Memcachedclientfacotry.create ("memcachedlegacy"); _memcachedclientcore= Memcachedclientfacotry.create ("Memcachedcore"); } [Httpdelete ("{Key}")] Public AsyncTask<iactionresult> Delete (stringkey) { varRemovecoretask =_memcachedclientcore.removeasync (key); varRemovelegacytask =_memcachedclientlegacy.removeasync (key); awaitRemovecoretask; awaitRemovelegacytask; returnOk (); }}
Using Factory mode to solve the problem of dependency injection in ASP.