📜 ⬆️ ⬇️

AcroDb. New data provider

The birth of a new CMS-system often begins with the design of the architecture and the implementation of the simplest blocks of this architecture.
Today, I am starting a series of articles dedicated to the new CMS implemented in C # and the .Net platform. The system is planned to be open source, and with these articles, I will try to describe all its elements in the order of their initial appearance and design another 2 years ago.
The beginning was the universal access layer to any data provider (either a relational database, or non-relational, or even its own database organization).
Who are interested, please under the cat.

Like everything that we want to make genius and simple, it must also be convenient, fast, and flexible. So I wanted to do with the data access layer. Please note any data :)
The easiest method for a programmer was always to use any ORM system. In the .Net Framework of this good enough, starting with the sources - NHibernate, Nolics , LINQ2SQL, Entity Framework, and a bunch of self-written ... What steps does a developer usually have to do to connect any ORM system to a project?

And everything seems to be cool. But! There comes a time when the customer does not like the subd (maybe it is expensive or slow, and then MongoDB appears which is on everyone’s lips). And the programmer has to rewrite and redo the entire data access layer. Again, almost all the same steps (please do not kick me fans of flexible architecture, in which everything has been provided for a long time, we are not talking about those tasks yet :)).
The idea was born to unify access to different providers by providing the CRUD operations interface and not providing relationships between tables (not all database providers know about relationships, but I will tell you how to do relationships in AcroDB in the following articles). What did I want to achieve?

What came of it? You can download the AcroDB project from the github site .
Let's see what you need to use any table with its automatic creation (a detailed example is in the AcroDbTest subproject in the samples).
First, you need to describe the interface of the future table:
[AcroDbEntity]
public interface IUser
{
Guid ID { get ; set ; }
string Name { get ; set ; }
}


* This source code was highlighted with Source Code Highlighter .

By marking it with the AcroDbEntity attribute, you indicate to the system that, based on this interface, you need to create a class in memory that implements it and use this class to work with the internal ORM system. not bad? :) go ahead.
Next, we need to configure the connection to the required data provider when the project is started (as long as MsSql and MongoDB are supported for testing):
static string [] SettingsCallBack( string name)
{
if (name == "MsSql" )
return new [] { @"server=OLEKSIY-PC\SQLEXPRESS;Database=acrodbtest;Trusted_Connection=True;" };
return new string [0];
}
static void Main()
{
DataContextFactory.SettingsCallback = SettingsCallBack;
DataContextFactory.Instance.ScanAssembly( typeof (MsSqlDataContext). Assembly );
//...
}


* This source code was highlighted with Source Code Highlighter .

The SettingsCallBack method is used to substitute configuration data for setting the data provider. in our example, this is the DBMS connection string.
The DataContextFactory class is a singleton that provides, on request, contexts for different data providers. In order for DataContextFactory to know about new data providers, it is necessary to feed an assembly to its ScanAssembly method, where information about such a provider is possible, and it will reflexively search.
Now we need to configure the data access context generator to use the provider:
AcroDataContext.DefaultDataContext = DataContextFactory.Instance.Get( "MsSql" );
AcroDataContext.ScanAssemblyForEntities( Assembly .GetExecutingAssembly());


* This source code was highlighted with Source Code Highlighter .

AcroDataContext is also a singleton, and the ScanAssemblyForEntities method searches for interfaces marked with the AcroDbEntity attribute in the assembly and creates prototype classes for use in ORM.
How to continue to use CRUD operations:
using ( var manager = AcroDataContext.Go)
{
var usr = manager.Provide<IUser>().Create();
usr.Name = "Some user name" ;
manager.Provide<IUser>().Save(usr);
manager.SubmitChanges();
}


* This source code was highlighted with Source Code Highlighter .

I will describe here only one line - AcroDataContext.Go. This is the creation of the context of the connection to the data provider is already connected and ready to work. Do not forget to close it with the Dispose method.
In order to create a table description in the data provider based on the description of your interface (in this case, the Users table with the primary key ID and the Name field with the nvarchar (255) type will be created), you need to call the method after scanning the interfaces for the interfaces AcroDataContext.PerformMigrations () ”. Migrations are made on the basis of SubSonic Migrations . Previously, they were done using SQL SMO.

This does not end the functionality of this library, but I will gladly describe additional elements if it is needed by someone. Also, the impatient can read the source code :)
For the first article, please do not kick much, I will try to answer all the questions :)

')

Source: https://habr.com/ru/post/88274/


All Articles