Oss. Core design and implementation of storage layer based on dapper package (expression parsing +emit)

Source: Internet
Author: User
Tags emit

Recently, while not busy, in the idea of a complete project to build an open source, as for the reasons and the entire project framework behind the article I will explain. Since a complete project, then data warehousing access is essential, this article I mainly introduce the new project (Oss.core) I to the storage layer of the simple thinking and implementation process (the current project is still in the construction phase), mainly focused on the following aspects:

1. Requirements of the Data warehousing layer

2. ORM Frame Selection

3. OSS. Core storage Layer Design implementation

4. Invoking the sample

You may be required to do so in the implementation section below. NET generics, delegates, extensions, expressions, etc. have a basic understanding. Because of these language features, it is convenient for us to unify the extraction of operation commonality.

I. Data warehousing layer Requirements

Since it is a complete project, data access is the most basic part of it, and data access is the most likely bottleneck for the entire project. In my division, its role is to be responsible for the input and output of the entire data, not only for the single database (and sometimes even docu), sometimes need to complete the implementation of a first-level cache, the logical layer provides the most basic data support.

The business is always changing, so the project also has the ability to evolve quickly, so I want the data layer to be relatively simple, structurally minimize complex coupling queries, and minimize unnecessary consumption in terms of performance, such as the massive use of reflection. At the same time, for each business object to complete the database level of the basic CRUD Unified encapsulation implementation. If necessary, you can also add cached updates with minimal changes. (for how to implement different cache storage policies for various modules, such as redis,memcached will be described in the article behind)

At the same time, for a slightly larger project, the fastest way to solve database access is to implement read-write separation, so I hope that this framework will be able to start at the bottom of the implementation of the read and write separation support, to avoid the late re-starting a lot of business code changes.

Two. ORM Frame selection

Of course, for simplicity and performance, direct ADO is theoretically a more efficient approach, but this can result in a large number of repetitive operation logic code, but also cause the code to be scattered, increasing the complexity of maintenance. As a technician, not only need to solve business problems to improve efficiency, but also to improve their efficiency, so I will choose an ORM framework to complete some of the basic work.

Currently on. NET system, open-source ORM Framework is many, such as: Entityframework,nhibernate, Ibatis.net,dapper and so on, each has its own characteristics, based on what I said earlier, to ensure efficiency, while minimizing the loss of performance, and providing support under the. NET Standard library. After this comparison, I chose to dapper this semi-automatic ORM as the basic framework of the storage layer, the reasons for the selection are as follows:

1. Its simple structure, the entire package is mainly concentrated in the Dapper.cs file, the volume is very small

2. The package is simple and powerful, the support of native SQL is very flexible

This almost eliminates the other framework, without any unnecessary setup, and basically you can invoke all the native ADO functions, the SQL statement completely own control, but do not need to care about the command parameter assignment, as well as the result entity transformation.

3. Performance-Efficient

Many of the ORM's entity mappings are done by reflection, which dapper the charm again, in the Commond parameter assignment, and the entity transformation of the key modules, The Reflection.Emit function is used to implement the assignment of MSIL at the compiler level indirectly, because its own code also requires the compiler to generate IL code. Dynamically creates an assignment delegate method at run time based on the Type property.

Three. OSS. Core storage Layer Design implementation

Through the dapper can be implemented in the database access part of a simple package, but I still need to manually write a lot of SQL statements, but also to do parametric processing, including data read and write separation. Then the implementation of these features I will be completed in the OSS.Core.RepDapper, in order to facilitate understanding, first put out a simple package after the method call transfer process:

650) this.width=650; "Src=" http://images2015.cnblogs.com/blog/154246/201705/154246-20170510011313488-454939920. JPG "width=" 642 "height=" 647 "style=" border:0px; "/>

In this diagram, we show a simple method invocation process, which revolves around a few core parts of this diagram, which I'll cover separately:

1. Interface design

Because I want this to be a complete sample project, I want to be able to be compatible with different databases, so the external warehousing access is based on the interface call. Of course, if your project does not have the need to switch databases, I would suggest to remove this link, directly in the base class to implement a singleton pattern, the business logic layer directly called.

The diagram can see that the interface layer is independent of the implementation part, I put the specific business entity model and interface in the OSS.Core.DomainMos class library, on the one hand, for the entity model in each module sharing, On the other hand, decoupling the dependencies between the business Logic layer (services) and the storage layer (REPS).

At the same time, most of the database access code in a project will be crud-based, so here I define a basic interface (IBASEREP), which contains the main methods (the expression section is described in the following):

650) this.width=650; "Src=" http://images2015.cnblogs.com/blog/154246/201705/154246-20170510013005785-96970101. PNG "width=" 618 "height=" 627 "style=" border:0px; "/>

The specific business data interfaces are inherited to the underlying interface, where the expression part is I made a package myself, which will be briefly described in the rear.

2. Storage base class implementation (BASEREP)

First of all, we implement the read-write separation of the two extensions, in fact, will eventually go through the Excute method, then this shows the concrete implementation of the method:

650) this.width=650; "Src=" http://images2015.cnblogs.com/blog/154246/201705/154246-20170510014658785-1011530644. PNG "width=" 619 "height=" 341 "style=" border:0px; "/>

Can be seen in this method provides a delegate for IDbConnection, provides the call layer free to use the Dapper method, unified the data access method entrance, convenient logging, and troubleshooting.

Secondly, in many projects there will be users and orders in different libraries of this kind of situation, because it involves the sub-library situation, so it is necessary to have the sub-class can modify the connection string ability, then here I through the form of a constructor, provides two nullable parameters:

650) this.width=650; "Src=" http://images2015.cnblogs.com/blog/154246/201705/154246-20170510014136035-485787805. PNG "width=" 621 "height=" 171 "style=" border:0px; "/>

As you can see, if you define your own connection string in a subclass, the subclass is custom-dominated, otherwise the default connection information is left.

  

Finally, we have implemented specific implementations of the underlying interface approach, for example:

650) this.width=650; "Src=" http://images2015.cnblogs.com/blog/154246/201705/154246-20170510015334504-671604400. PNG "width=" 618 "height=" 188 "style=" border:0px; "/>

At the same time, in order to ensure the inclusion of cache processing in subclasses, the virtual method (virtual) is used to ensure that subclasses can be rewritten.

3. Connection-based extensions

This place is mainly divided into two parts, a. Expression parsing, and parameterized processing B. Extended connection Insert,update ... There is no way to extend dapper such as:

A. Friends who are familiar with expression expressions should be more aware that the expression itself is a tree interface, and according to different types, it is possible to parse its sub-expressions continuously until there is no possibility of continuing parsing. So this is very simple recursive iterative, according to its different nodetype can assemble different SQL elements, because the code is longer, See the SqlExpressionVisitor.cs class under GitHub, where the assignment portion of the parameter is not reflected, but the reflected emission is used, and the code is described in SqlParameterEmit.cs

B. With the extension of the expression, you can get the corresponding SQL and parameters, through the This extension connection method, code see ConnoctionExtention.cs

  

Four. Invoking the sample

1. We define a simple Userinfomo entity (including properties such as mobile)

2. Define the interface Iuserinforep:ibaserep

3. Define implementation class Userinforep:baserep, Iuserinforep

Without adding additional code, we can complete the following call:

650) this.width=650; "Src=" http://images2015.cnblogs.com/blog/154246/201705/154246-20170510020955629-1374517759. PNG "width=" 627 "height=" 469 "style=" border:0px; "/>



Oss. Core design and implementation of storage layer based on dapper package (expression parsing +emit)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.