Dottext source code reading (4)-DTO and data access

Source: Internet
Author: User
How is DTO implemented in dottext? These are the implementation content of the Three-layer system. Many senior people have their own opinions on the use of DTO, and there are also a lot of arguments. However, what I want to talk about here is why dottext uses DTO. I understand that the author wants to maintain a layer-3 system through DTO, in order to solve the mutual dependency between layers of coupling, reserve sufficient maintenance space for updates and upgrades between layers. Dottext. Framework. Data. idtoprovider defines the DTO interface, which involves the following operations on the object machine: Entry That is, Article The object declaration is in entry. CS under the components directory. Note that this class inherits the iblogidentifier interface and declares the [serializable] attribute. Almost all defined object types are similar to this class. Links Favorite link categories Category. Note that the system category of the blog is stored together with that of each blog. The-1 blog is used to distinguish the system-defined category. Stats Statistics Configuration Configuration keywords Blog Keyword: Images Album Archives Archive scheduledevents Scheduling event Logger Log object Rate Click SECURITY STATISTICS Authentication mailpolicy The iblogidentifier interface specifies which blogid the class must belong to. This is easy to understand, because both articles, statistics, personal links, favorites, and folders are private. In addition to object classes, collection classes of corresponding object classes are also implemented. For data binding, many people like to use the entity collection class instead of dataset. I am also such a person. These object collection classes are also marked with the [serializable] attribute. You can also use serialization to configure operations on these object classes. dottext defines the idtoprovider interface to define DTO operations, specifically in dottext. framework. under the data directory, this interface needs to be implemented by other specific classes, but it reflects the author's design philosophy: it is not to bind the implementation to the data layer of the object, which can be used for reference. To further implement your own ideas, dottext also specially clips a data layer abstraction, idbprovider, which implements data access to various DTC entities, however, the returned idatareader and dataset are all defined to encapsulate specific databases. The author of dottext is writing Code A lot of classification comments are made. For specific implementation of the data layer, my version is based on SQL Server, and all specific data operations are performed in sqldataprovider under the Data Directory. CS, this class implements idbprovider, but we see almost all of them are stored procedure calls, and there are more than 110 SQL versions of dottext, so read carefully the access details of these data layers, it takes a lot of time. However, after clarifying these clues, we can know how to read and even implement changes. . How does the system implement flexible configuration of data access? For example, the final operation for posting an article falls in admin \ usercontrols \ entryeditor. on ascx (detailed analysis may be added later), the Code is as follows: Private void updatepost () { If (page. isvalid) { String successmessage = constants. res_successnew; Try { Entry entry = new entry (entrytype ); Entry. Title = txbtitle. text; ...... Entry. blogid = config. currentblog (context). blogid; If (postid> 0) { Successmessage = constants. res_successedit; Entry. dateupdated = datetime. Now; entry. entryid = postid; entry. Link = dottext. Framework. configuration. config. currentblog (). urlformats. entryurl (entry ); If (chkismoveto. Checked) { Entry. posttype = entry. posttype ^ (posttype) 3 ); } Entries. Update (entry ); ...... If (postid> 0) { // Linkcollection lc = new linkcollection (); Arraylist Al = new arraylist (); Int COUNT = cklcategories. Items. count; If (chkismoveto. Checked) { Count = 0; } // Document category For (INT I = 0; I <count; I ++) { If (cklcategories. items [I]. Selected) { Al. Add (int32.parse (cklcategories. items [I]. Value )); } } // Website category ...... } Catch (exception ex) {This. Messages. showerror (string. Format (constants. res_exception, Constants. res_failureedit, Ex. Message )); } Finally { Results. collapsible = false; } } } The entry here belongs to the DTO type. Components Which is explained below. If this is the first new article, the following code will be executed: Entries. Update (entry ); The following command is executed: Public Static IntCreate (Entry entry) { ReturnCreate (entry,Null); } Static Method, final call Public Static IntCreate (Entry entry,Int[] Categoryids) { Handlermanager. precommit (entry, processaction. insert ); IntResult = dtoprovider. instance (). Create (entry, categoryids ); If(Result> 0) { Handlermanager. postcommit (entry, processaction. insert ); } ReturnResult; } Let's focus on Int Result = dtoprovider. instance (). Create (entry, categoryids ); To execute this statement, consider the following: Dtoprovider In the providers Directory: it has a static declarative constructor. Static Dtoprovider () { Dtoproviderconfiguration dtopc = config. settings. blogproviders. dtoprovider; Idto = (idtoprovider) dtopc. instance (); } It is used to execute the construction before the method of the class is called statically (this is equivalent to the singleton mode ). In this case, the dtoprovider configuration will be obtained using the configuration system mentioned by the former user. Dtoproviderconfiguration Yes [Xmlroot ("dtoprovider")] attribute. dtoproviderconfiguration is obtained from the XML snippet obtained in the <blogproviders> section. Note that dtoproviderconfiguration inherits from an abstract class baseprovider. Config. settings. blogproviders obtains the specific blogprovider class through deserialization, but we only want to obtain the attributes of dtoprovider, And the configuration in my hands is dottext. framework. data. datadtoprovider (note that this class implements the idtoprovider interface ). The dtoproviderconfiguration type is actually the actual implementation of the abstract class baseprovider, but with the [xmlroot ("dtoprovider")] attribute (deserialization is allowed) added, a provider type is obtained. Idto = (idtoprovider) dtopc. instance (); dtopc. instance (); the Public object instance () in baseprovider (abstract class) is called () { Return activator. createinstance (system. type. GetType (this. providertype )); } As you can see, this is a dynamic generation method and also uses the reflection principle. The providertype Declaration for this class is like this [xmlattribute ("type")] Public String providertype { Get {return _ type ;} Set {_ type = value ;} } You can see that this is the type value read from the configuration file. The specific project value I have viewed is: dottext. framework. data. datadtoprovider, dottext. in this way, the datadtoprovider class is instantiated, and datadtoprovider implements the idtoprovider interface. Through such a "complex" process, Dtoprovider statically constructs an interface (dtoprovider. instance () Statement) idtoprovider that can access the database layer, while the interface function can be implemented in idtoprovider Int Create (Entry entry,Int[] Categoryids); the details of the SQL data layer are as follows (see implementation class Datadtoprovider ): Public IntCreate (Entry entry,Int[] Categoryids) { If(Entry. posttype = posttype. pingtrack) { ReturnDbprovider. instance (). insertpingtrackentry (entry); // dbprovider explained later } Formatentry (RefEntry ); If(EntryIsCategoryentry) { Entry. entryid = dbprovider. instance (). insertcategoryentry (categoryentry) entry )); } Else { Entry. entryid = dbprovider. instance (). insertentry (entry ); If(Categoryids! =Null) { Dbprovider. instance (). setentrycategorylist (entry. entryid, categoryids ); } } If(Entry. entryid>-1)// & Config. settings. Tracking. usetrackingservices) { Entry. Link = dottext. Framework. configuration. config. currentblog (). urlformats. entryurl (entry ); Config. currentblog (). lastupdated = entry. datecreated; } Else { // We Need To fail here to stop the postcommits? Throw NewBlogfailedpostexception ("your entry cocould not be added to the datastore "); } ReturnEntry. entryid; } Here, the entry object's physical storage operation is implemented. The Dbprovider is worth noting Static Dbprovider () { Dbproviderconfiguration DPC = config. settings. blogproviders. dbprovider; Dp = (idbprovider) DPC. instance (); DP. connectionstring = DPC. connectionstring; } No. It is the same static structure as dtoprovider. Operate object through serialization to specific dB StorageDottext. Framework. Data. sqldataprovider, dottext. framework. The following code is contained in the db operation for creating an entry object: Entry. entryid = dbprovider. instance (). insertentry (entry ); Sqldataprovider The insertentry operation details are as follows: Public IntInsertentry (Entry entry) { Sqlparameter [] P = { Sqlhelper. makeinparam ("@ title", sqldbtype. nvarchar, 255, entry. Title ), Sqlhelper. makeinparam ("@ titleurl", sqldbtype. nvarchar, 255, datahelper. checknull (entry. titleurl )), Sqlhelper. makeinparam ("@ text", sqldbtype. ntext, 0, entry. Body ), Sqlhelper. makeinparam ("@ sourceurl", sqldbtype. nvarchar, 200, datahelper. checknull (entry. sourceurl )), Sqlhelper. makeinparam ("@ posttype", sqldbtype. Int, 4, entry. posttype ), Sqlhelper. makeinparam ("@ Author", sqldbtype. nvarchar, 50, datahelper. checknull (entry. Author )), Sqlhelper. makeinparam ("@ email", sqldbtype. nvarchar, 50, datahelper. checknull (entry. Email )), Sqlhelper. makeinparam ("@ description", sqldbtype. nvarchar, 500, datahelper. checknull (entry. Description )), Sqlhelper. makeinparam ("@ sourcename", sqldbtype. nvarchar, 200, datahelper. checknull (entry. sourcename )), Sqlhelper. makeinparam ("@ dateadded", sqldbtype. datetime, 8, entry. datecreated ), Sqlhelper. makeinparam ("@ postconfig", sqldbtype. Int, 4, entry. postconfig ), Sqlhelper. makeinparam ("@ parentid", sqldbtype. Int, 4, entry. parentid ), Sqlhelper. makeinparam ("@ entryname", sqldbtype. nvarchar, 150, datahelper. checknull (entry. entryname )), Blogidparam, Sqlhelper. makeoutparam ("@ ID", sqldbtype. Int, 4) }; Nonqueryint ("blog_insertentry", P ); Return(Int) P [14]. value; } See no. This is a specific SQL stored procedure call code. In this way, the configuration file is used to specify the dtoprovider and dbprovider instances of blogproviders. Different Configurations allow you to replace them with different instances. For example, you can replace the DB layer with MySQL. or the specific table operation of orcal. For more information, see: 1, Static constructor 2, activator. createinstance (system. type. GetType (this. providertype); this method uses reflection to create an object instance. In addition, we need to understand that dottext uses a configuration file to dynamically specify the elaborate design of DTO and DB operations (although it is somewhat confusing ). Unfortunately, I found that there seems to be a problem with the version of the blog garden. Many operations, they directly manipulate the database, this may lead to some misunderstandings for me who are not familiar with the source version. The above analysis hopes to eliminate your questions. I stayed up all night :)

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.