Home .NET Active Record Pattern

Active Record Pattern

by admin

I want to talk about using Active Record pattern for C# in practice.Such class implements the extraction and recording of the structure in the database.The business logic is taken to the next levels of abstraction, where you can work with such an object like with a normal structure.
The central case I will consider for the example is that of the Country from a database, which is often read but very rarely changed.
Using active record object in the business logic code looks like this :

Countryrussia = Country.All[“Russia”];

Country does not have a public constructor, and retrieving objects is only possible by calling the Dictionary<string, Country> All
Now more about how this class is arranged from the inside.

Record constructor

public readonlystring name;private Country(IDataRecord record){name = record.GetString(0);}

Thanks to the privacy of the constructor, we can hope to apply the constructor correctly.And only inside the class.
For example like this :

private static Dictionary<string, Country> _all= null;private static Dictionary<string, Country> LoadDictionary(){_all= new Dictionary<string, Country> ();IDataReader reader = DBWrapper.GetReader(sqlSelect);try{while (reader.Read()){Country item = new Country(reader);_all.Add(item.name, item);}}finally { reader.Close(); }return _all;}

sqlSelect – private constant, to read all records with the desired order of fields for the constructor.
DBWrapper – is a self-written class encapsulating the database operation. Thanks to it, at this level we only have to work with interfaces, without specifying a specific implementation.
Add – adding a new entry to the general registry, hidden for code brevity in the article.

Vocabulary All

Nothing complicated here either :

public static Dictionary<string, Country> All{ get {return _all ?? LoadDictionary();}}

As a result, we have a delayed loading of the directory on the first call.
Private variable _all is used only in this piece of code. Unfortunately, C# does not allow to limit its usage to less than the whole class. That leaves the danger of using it in public methods, for example. That will be a real problem when working in several threads.
This is the first question I want to discuss : how to limit the visibility of the _all variable more?

Multithreading synchronization

This method of delayed loading is not yet suitable for multithreading, so I added the class LoadStatus
private static readonly LoadStatusstatusCountryList = new LoadStatus(“country”);
The name for the status is needed to identify it in the list of statuses of all directories. But more about that later.

private static Dictionary<string, Country> _all = null;public static Dictionary<string, Country> All{ get {if ( !statusCountryList.IsCompleted ) {lock (statusCountryList) {if ( !statusCountryList.IsCompleted ) {statusCountryList.Start();_all = new Dictionary<string, Country> ();IDataReader reader= DBWrapper.GetReader(sqlSelect);try{while (reader.Read()) Add(new Country(reader))statusCountryList.Finish(_all.Count);}catch Exception ex { statusCountryList.Error(ex); }finally { reader.Close(); }}}}return _all;}}

A lot of pasta, but now we have multithreading and a report on the health of our directory, as a bonus from the architecture.
LoadStatus Hides the synchronization and collection of directory health data.
In addition, through zeroing LoadStatus it is possible to reload the directory on the fly.
It was for the sake of this feature that I gave up readonly for _all

Class Generic

The solution turned out to be so handy and elegant that I use it in dozens of references in all my projects. And there is a great desire to turn this code into genericclass
However, the C# syntax does not allow this.
What do you think of this decision?
What might be some ways to turn this solution into a generic ?

You may also like