ArticleDirectory
- Business logic business entity Layer
- Interface and logic Separation
- Interface/implementation interface layer and interface Implementation Layer
I divided MIS software into four implementation layers and three-layer architecture.
Businesslogic business entities are generated by llbl Gen,CodeGenerator generation
Interface data access interface is generated by code Smith based on the data access interface generated by the Entity
The Manager interface implements the code of the data access interface generated by the entity, which is generated by code Smith.
Drag controls on the UI interface layer and bind data to the interface
Business logic business entity Layer
Using ORM as the basic technology for data access, business entities include the relationship logic between data, instead of the entities used to fill data.
The above structure is automatically generated by llbl gen. It has generated entities, entity verification types, data access interfaces, and related auxiliary types for us.
The company entity in the company registration. Its definition is as follows:
[Serializable]Public Partial ClassCompanyentity: commonentitybase// _ Llblgenpro_user_code_region_start additionalinterfaces// _ Llblgenpro_user_code_region_end
{ # Region Class member declarations Private Entitycollection <moduleentity> _ modules; // _ Llblgenpro_user_code_region_start privatemembers // _ Llblgenpro_user_code_region_end # Endregion # Region Statics Private Static Dictionary < String , String > _ Customproperties; Private Static Dictionary < String , Dictionary < String , String >>_ Fieldscustomproperties; /// <Summary> all names of fields mapped onto a relation. usable for In-memory filtering </Summary> Public Static Partial Class Membernames {/// <Summary> member name modules </Summary> Public Static Readonly String Modules = "Modules" ;} # Endregion /// <Summary> static ctor for setting up custom property HashTables. is executed before the first instance of this entity class or derived classes is constructed. </Summary> Static Companyentity () {setupcustompropertyhashtables ();} /// <Summary> ctor </Summary> Public Companyentity ():Base ( "Companyentity" ) {Initclassempty ( Null , Null );}.....}
The entity code generated by the llbl Gen designer has several features:
- Generate a constructor for multiple purposes ). We often use constructor without parameters and methods with primary key values.
[Editorbrowsable (editorbrowsablestate. Never)]ProtectedCompanyentity (serializationinfo, streamingcontext context ):Base(Info, context ){If(Serializationhelper. Optimization! = Serializationoptimization. Fast) {_ modules = (entitycollection <moduleentity>) info. getvalue ("_ Modules",Typeof(Entitycollection <moduleentity> ));This. Fixupdeserialization (fieldinfoprovidersingleton. getinstance ());}// _ Llblgenpro_user_code_region_start deserializationconstructor// _ Llblgenpro_user_code_region_end}
This constructor is used when an object is serialized, for example, when. Net remoting remotely returns an object.
- Generate special settings of commonly used attributes for Custom Attributes of fields that contain custom attributes. For example, companyentity. companycode, in order not to distinguish the case sensitivity of companycode, must be in uppercase, we can add the custom attribute requiredcap here, and thenProgramRead this attribute during runtime and set the uppercase/lowercase character of the control.
Private Static Dictionary < String , String > _ Customproperties; Private Static Dictionary < String , Dictionary < String , String >>_ Fieldscustomproperties; Private Static Void Setupcustompropertyhashtables () {_ customproperties = New Dictionary < String , String > (); _ Fieldscustomproperties = New Dictionary < String , Dictionary < String , String >>(); Dictionary < String , String > Fieldhashtable; fieldhashtable = New Dictionary < String , String > (); _ Fieldscustomproperties. Add ( "Companycode" , Fieldhashtable); ...... dictionary < String , String > Fieldcustomproperties = companyentity. fieldscustomproperties [ "Companycode" ]; String Requiredcap = fieldcustomproperties [ "Requiredcap" ];
When the value of the read custom attribute requiredcap is true, set the charachtercasing attribute of the control.
Interface and logic Separation
Let's look at how business computing of business entities occurs. The sample code is as follows:
Protected Override Void Onfieldvaluechanged ( Object Originalvalue, ientityfield2 field ){ Base . Onfieldvaluechanged (originalvalue, field ); Switch (Companyfieldindex) field. fieldindex ){ Case Companyfieldindex. driverassembly: onchangedriverassembly (( String ) Originalvalue );Break ;}} Private Void Onchangedriverassembly ( String Originalvalue ){ If ( This . Driverassembly = originalvalue | string. isnullorempty (driverassembly )) Return ; This . Drivertype = basecommon. getprojectname (moduletype. businesslogic, driverassembly );}
When I change the current interface plug-in assembly in the interface, it will automatically read the type information and project name information of this Assembly for me. To understand this method, you must first understand the Data Binding Technology in. NET development. The data source control is equivalent to a bridge connecting the data entity and interface control. When a value is assigned to the data source control, the control reads the value of the data entity. When the value of the control in the interface changes, the data source control automatically writes the changed data back to the data entity. Therefore, when the value of the data object changes, we can register the corresponding change event for business logic processing. The data source control reads the changed data object Value and presents it on the interface. Almost all business logic is programmed in this way, and the interface and logic are separated.
After the interface is separated from the logic, the interface is used to bind the control to the data source control, and then generate a data read/write interface using code Smith:
Public Override Entitybase2 loadentity ( String Refno) {iitemmanager manager = clientproxyfactory. createproxyinstance <iitemmanager> (); itementity customer = manager. getitem (refno ); Return Customer ;} Public Override Void Deleteentity (entitybase2 entity) {itementity user = (itementity) entity; iitemmanager = clientproxyfactory. createproxyinstance <iitemmanager> (); manager. deleteitem (User );} Public Override Void Saveentity (entitybase2 entity) {itementity user = (itementity) entity; iitemmanager = clientproxyfactory. createproxyinstance <iitemmanager> (); manager. saveitem (User );}
All interface code related to database read/write in the system is implemented in this way.
Interface/implementation interface layer and interface Implementation Layer
Both interfaces and their entities are generated using the code Smith template, which is highly efficient. Supplier Interface
Public Interface Ivendormanager {vendorentity getvendor (system. string vendorno); vendorentity getvendor (system. string vendorno, iprefetchpath2 prefetchpath); vendorentity getvendor (system. string delimiter, delimiter, delimiter fieldlist); entitycollection delimiter (delimiter filterbucket); entitycollection identifier (delimiter filterbucket, isortexpression sortexpression); entitycollection identifier (delimiter filterbucket, isortexpression sortexpression, prefetchpath ); entitycollection objects, entitycollection entitiestodelete,String Seriescode ); Void Savecollection (entitycollection vendors ); Void Deletevendor (vendorentity vendor ); Bool Isvendorexist (system. String vendorno ); Bool Isvendorexist (irelationpredicatebucket filterbucket ); Int Getvendorcount (irelationpredicatebucket filterbucket); vendorentity clonevendor (system. String vendorno ); Void Postvendor (system. String vendorno ); Void Postvendor (vendorentity vendor ); Void Approvalitem (entitycollection vendors );}
The following is an example of the Manager type code that implements the interface:
Public Class Vendormanager: Foundation. Common. managerbase, ivendormanager { Public Vendorentity getvendor (system. String vendorno ){ Return Getvendor (vendorno, Null );} Public Vendorentity getvendor (system. String vendorno, iprefetchpath2 prefetchpath ){ Return Getvendor (vendorno, prefetchpath, Null );} Public Vendorentity getvendor (system. String vendorno, iprefetchpath2 prefetchpath, excludeincludefieldslist fieldlist) {vendorentity _ vendor = New Vendorentity (vendorno ); Using (Dataaccessadapterbase adapter = getcompanydataaccessadapter ()){ Bool Found = Adapter. fetchentity (_ vendor, prefetchpath, Null , Fieldlist ); If (! Found) Throw New Foundation. Common. recordnotfoundexception ( "Invalid vendor" );} Return _ Vendor ;}
In the interface layer or the entity layer, use the following interface to access the interface:
Icompanymanager _ companymanager = clientproxyfactory. createproxyinstance <icompanymanager> (); companyentity _ Company = _ companymanager. getcompany ("Kingston ")
If the Distributed Technology (. NET remoting, WCF) is not used, the createproxyinstance method directly returns the entity-type instance of the icompanymanager interface for the interface to call. If the. NET remoting technology is applied, the following method is used to generate the Server Object: the entity object generated by the client is a remote proxy that points to the remote object:
Remotingconfiguration. registeractivatedservicetype (type );
The benefits of separating interfaces from implementations are obvious here. You do not need to change the code when switching the deployment mode (standalone, distributed.