How can I put a file in cache in dotnet? - c#

I have been trying to implement localization in .NET 6.0 via JSON files, and a way of doing that (please note that the resources are provided as JSONs with different formats eg one has nested objects and the other simply key-values) was to implement the IStringLocalizer interface and of course every time on lookup in something doesn't exist in the IDistributedCache then load the file, parse it accordingly and insert the key-value pair in the distributed cache.
However, upon every entry that doesn't exist in the distributed cache, I will have to load the file (which is IO lookup and I am guessing rather expensive for the app, especially if there is a cache miss frequently) and get the value depending from which file I want to read from.
Is there a way to load the file when startup is called and simply inject it to the localizer extension that I have made?

You can invoke your service which manage localization in Startup like that
app.Services.GetService<IMyLocalizationService>().LoadLocalization()
In that moment DI should be builded so you should have access to IDistributedCache

Related

Best way to store data (single object) in Web API project without database

My project group and I are to develop a generic workflow system, and have decided to implement a single Node (a task in the workflow) as a C# Visual Studio Web API project (Using the ASP.NET MVC structure).
In the process of implementing a Node's logic, we've come across the trouble of how to store data in our Node. Our Node specifically consists of a few lists of Uri's leading to other Nodes as well as some status/state boolean values. These values are currently stored in a regular class but with all the values as internal static fields.
We're wondering if there's a better way to do this? Particularly, as we'd like to later apply a locking-mechanism, it'd be prefereable to have an object that we can interact with, however we are unsure of how we can access this "common" object in various Controllers - or rather in a single controller, which takes on the HTTP requests that we receive for ou Node.
Is there a way to make the Controller class use a modified constructor which takes this object? And if so, the next step: Where can we provide that the Controller will receive the object in this constructor? There appears to be no code which instantiates Web API controllers.
Accessing static fiels in some class seems to do the trick, data-wise, but it forces us to implement our own locking-mechanism using a boolean value or similar, instead of simply being able to lock the object when it is altered.
If I am not making any sense, do tell. Any answers that might help are welcome! Thanks!
Based on your comments, I would say the persistence mechanism you are after is probably one of the server-side caching options (System.Runtime.Caching or System.Web.Caching).
System.Runtime.Caching is the newer of the 2 technologies and provides the an abstract ObjectCache type that could potentially be extended to be file-based. Alternatively, there is a built-in MemoryCache type.
Unlike a static method, caches will persist state for all users based on a timeout (either fixed or rolling), and can potentially have cache dependencies that will cause the cache to be immediately invalidated. The general idea is to reload the data from a store (file or database) after the cache expires. The cache protects the store from being hit by every request - the store is only hit after the timeout is reached or the cache is otherwise invalidated.
In addition, you can specify that items are "Not Removable", which will make them survive when an application pool is restarted.
More info: http://bartwullems.blogspot.com/2011/02/caching-in-net-4.html

Wcf services and Db settings?

I was asked to build different WCF services where each do other work against sql.
We have 5 db's. All db's+connection string are in 1 xml file. ( file-system file)
The services are hosted under WAS iis 7.5.
since each service should read from db , each service references a DAL dll file.
So here are our components :
I would like to read the xml data to CACHE ( at the first request) and from now on - read from cache. (reading the file each reqeust is out of the question).
idea #1 = the dll , in his ctor , at first request will read the xml file and load it to its cache.
so the dal will look like this :
so now each service can access the DLL's cache object via property. ( one advantage is when dealing with cache dependency on a single file - so when it is changing , we should reload only to one location).
idea #2 = when service is up , load the xml into its cache.
so now , each service will look like this :
Service #1 :
Service #2 :
..
the downside is many cache dependencies on the same file
Question :
By the best practice experience and by design pattern POV : which is the preferred way ?
p.s. the xml file change frequency 1/(1 month)
First of all, when it comes to file system, on Windows Server OS, there's a built in cache layer above the disk. So you probably won't feel much difference regarding disk reads. Of course, parsing the same input again and again is not a good practice, so the parsed (tokenized) xml should be cached.
The design needs more clarifications:
Is there only a single instance of a DAL class, shared among the 5
services? Or maybe the property described in idea 1 is static?
In idea 2: when the file changes and, say, connection string 4 is
changed (and everything else remains the same) - only service 4
should be reloaded?
If a specific service is reloaded - does it cause some kind of
inconsistency with other (non fresh) services?
Update:
I'm still not sure I fully understand the scenario, but here's what I'd do as far as I understand:
The DAL should expose an interface for all data related operations.
Let's say it's IDataGateway
Now, each service has should have a reference to an instance that implements IDataGateway. The service should not be aware of the caching mechanism at all. It just consumes data from the interface.
So all of the caching is done outside the service, in terms of classes and code organization.
Now, the caching layer, in turn, implements IDataGateway, and also consumes a non cached instance of IDataGateway. That's called Decorator pattern. The non cached instance is to be injected in the constructor.
Now, I suggest each service has its own instance of a cached IDataGateway. It's simpler than a singleton (to me, at least). And since data is not shared between services, then we're cool. If, however, data is shared between the services, than a single instance should be used.
Back to those 5 instances, and to the xml file.
We want to monitor this file once it changes, right? We could easily write our own file monitor, or use the one that comes with the framework, or we could see the source code of the CacheDependency class.
The simplest way to do it is to have 5 monitors watching the same file. That's not much of a performance penalty, since timers are quite "cheap".
If, however, you'd like to reduce the resources being used by your system, then you could use a single monitor, having it raise its event of FileChanged or something like that. Each of the 5 cached implementations (those 5 instances) of IDataGateway should have this monitor injected in its constructor, and wire up its own event listener to the FileChanged event.
Once this event is triggered, all of the 5 cached instances of IDataGateway would invalidate their inner cache, thus they should clear their in-memory entries.
On the next call, the cached implementation of IDataGateway would try to take the non existing data from its in-memory cache, but obviously nothing would be there, so it should go on executing the same method in the non-cached implementation of IDataGateway, and populate its cache.
That's my design, HTH...
For me the question comes down to who really needs to know about connection strings: the DAL or the Service? Obviously it's the DAL. The service doesn't (or shouldn't) care what kind of data store the DAL is using - could be a bunch of CSV's on the disk (yikes!) for all it cares. So, it wouldn't make sense to put the connection strings in the services. The DAL needs the connection info, so the DAL should take care of finding it and caching it.

What options do I have for storing data without using Sql?

How can I store data (for example: Config file) in MVC without using Sql, when im using third-party class, when I have no access to the Server proparty?
I want the data to remain in a subdirectory of the website.
You could use any format you like for the files: XML, JSON, ... whatever you feel comfortable with. There are serializers built directly into the framework which will allow you to directly serialize/deserialize your objects into those formats.
Just one thing to bare in mind if you decide to go that route: multithreading. Make sure that you properly synchronize the access to this file or you could get corrupted data if you have concurrent readers and writers. Think for example user A saving his settings (and thus writing to the file) while User B is reading his settings => you will end up with corruption. One technique to properly synchronize access to such shared resource is to use the ReaderWriterLockSlim class.
If all you need to do is store a config file, why not keep it in the web.config? Any class library you reference which requires its own configuration from a .config file will look in your app's web.config.

Reset Static fields on change in INI file

I have a C# class library which reads an INI file to obtain the value for a parameter
for e.g. (debug=on)
Now on every call and some times multiple times in one call I have to check this INI and this leads to I/O overhead.
To overcome this I made the parameter in code to be static so at the load time it will check the INI and will store the result.
But now I have to add this condition that reset your IIS or kill your windows form in case you change the INI value.
Note: I dont want to use configuration files (app.config/web.config) as this library is used in various projects (forms/web/services).
So in your opinion what is the best way to Reset Static fields on change in INI file without doing an IIS Reset etc.
Any reason it has to actually be static fields? I would suggest having some sort of configuration interface which you can pass around as a dependency to the bits that need it. You can then have three implementations:
A "fake" with writable properties used for testing
A "file reading" implementation which reads a file on construction, and is then immutable
A "file watching" implementation which has the idea of its current configuration (and instance of the previous one) and replaces its "current" one when the file changes, via FileSystemWatcher. Calls to read the configuration properties simply delegate to the "current" configuration.
This approach will lead to a much better testing experience - both for within your class library and potentially for code which uses your class library.
If you really, really need a single place that you can always get at a configuration, you could always use the above but have a single static field which refers to the "file watching" implementation.
Look into using a FileSystemWatcher

How to provide a plugin with data capabilities?

I have an application in which i want to provide the people who write plugins to it (plugins are made by implementing a basic interface, then i load the .dll). I want to give them the possibility to create settings and save data in my existing database. I would like to do this without having to create a table for each plugin - but if its required im willing to do it. I have come up with two basic scenarios:
Give the plugin an interface, where it can get a Dictionary and serialize it to xml and save it in my database.
The plugin must be contained within a .zip file with a manifest file (my own invention) where it has a create sql script and a drop script for tables.
The first has limitations towards complex data types. The second has a larger complexity in the plugin, since it needs to be within a .zip file and unpacked etc...
Please advice on either of these approaces, or alternatives.
Cheers
Your plugin constructor should recieve SettingRepository object, which provide methods for storing the setting and save them back
public MyCustomPlugin(PluginId id, SettingsRepostiory settingsRepository)
{
_id = id;
_settingsRepository = settings;
}
public void SomePluginMethod()
{
PluginSettings setting = settingsRepository.Settings.WithId(_id);
//...
}
where PluginSettings indeed could be a dictionary, that serialized to XML
I am a little hesitant toward option 2, as you are giving a third party access to essentially write SQL directly against your database. However, option 1 seems feasible and safe. As #Euphoric said, you can use multiple keys if you need to do more complicated things.
1st aproach seems fine. If application wants to save complex configuration, it can either save it as multiple keys or serialize some complex configuration object into string.
It depends how complex the plugins are.
First approach is perfect if the pugins need only settings. In this situation I don't see any limitation of the first method.
The second method does not brig anything new. You can get the same info that is in the manifest file in a datastructure and retrieve it from the plugin interface method. This is easyer because you manage only the dll file. Also if the file is very complex you can put it in a resource in the dll.
In your database you can save in a table something like: plugin_name_settingname, value into a settings table that you use for all plugins.
I once had to suport a plugin mechanism where plugins nedded their own tables.
In this case you can retrieve the new tabels schema and names in the interface method that plugin implenet. Then you need to create that in the database. Is like an insall for the plugin.

Categories