ArticleDirectory
- Preface
- Interface-Oriented Programming
- Should the warehousing interface be designed as basic operation interface and extended operation interface?
Preface
The underlying implementation of the linq to SQL and EF era basically uses the repository module, that is, the warehousing mode. In fact, it is to close the most basic operations OF THE ORM entity, the external layer does not disclose the operation implementation details.
Interface-Oriented Programming
One rule and multiple implementations may be the most intuitive impression of an interface. For example, after a storage is defined, You can implement it using LINQ to SQL, you can also use EF to implement it, or use ado.net to implement it, but it always exposes a stable interface, which is called irepository.
Should the warehousing interface be designed as basic operation interface and extended operation interface?
This is the focus of today's discussion. we extract the most basic operations of warehousing and put them in the irepository interface, which is called the basic operation interface; put the set operations and other additional operations in the iextensionrepository interface, we call it an extended operation interface, and we create an icompleterepository interface that completes the function. It integrates the first two interfaces. When the caller requires the functionality of irepository and iextensionrepository, we must use icompleterepository to declare an object. For simple operations, we only need to use irepository to declare an object.
The irepository interface can be defined as follows:
Public Interface Irepository <tentity>Where Tentity: Class { /// <Summary> /// Add an object and submit it to the Data Server /// </Summary> /// <Param name = "item"> Item to add to Repository </Param> Void Insert (tentity item ); /// <Summary> /// Remove entity and submit to Data Server /// If the table has constraints, delete the sub-table information first. /// </Summary> /// <Param name = "item"> Item to delete </Param> Void Delete (tentity item ); /// <Summary> /// Modify the entity and submit it to the Data Server /// </Summary> /// <Param name = "item"> </param> Void Update (tentity item ); /// <Summary> /// Get all elements of type {t} In Repository /// </Summary> /// <Returns> List of selected elements </Returns> Iqueryable <tentity> GetModel (); /// <Summary> /// Returns an object based on the primary key. /// </Summary> /// <Param name = "ID"> </param> /// <Returns> </returns> Tentity find ( Params Object [] ID );}
For extended functional interfaces, we can define them as follows:
/// <Summary> /// Extended repository Operation Specifications /// </Summary> Public Interface Iextensionrepository <tentity> Where Tentity:Class { /// <Summary> /// Add collection /// </Summary> /// <Param name = "item"> </param> Void Insert (ienumerable <tentity> ITEM ); /// <Summary> /// Modify a set /// </Summary> /// <Param name = "item"> </param> Void Update (ienumerable <tentity> ITEM ); /// <Summary> /// Delete collection /// </Summary> /// <Param name = "item"> </param> Void Delete (ienumerable <tentity> ITEM ); /// <Summary> /// Extended update method, only supported for ef /// </Summary> /// <Param name = "entity"> </param> Void Update (system. LINQ. Expressions. Expression <action <tentity> Entity ); /// <Summary> /// Get the delayed result set according to the specified Protocol /// </Summary> /// <Param name = "Specification"> </param> /// <Returns> </returns> Iqueryable <tentity> GetModel (Commons. entity. Specification. ispecification <tentity> Specification ); /// <Summary> /// Get the latency result set based on the specified Lambda /// </Summary> /// <Param name = "Predicate"> </param> /// <Returns> </returns> Iqueryable <tentity> GetModel (system. LINQ. Expressions. Expression <func <tentity, Bool > Predicate ); /// <Summary> /// Obtain entities based on specified conventions /// </Summary> /// <Param name = "Specification"> </param> /// <Returns> </returns> Tentity find (Commons. entity. Specification. ispecification <tentity> Specification ); /// <Summary> /// Obtain the object based on the specified Lambda /// </Summary> /// <Param name = "Predicate"> </param> /// <Returns> </returns> Tentity find (system. LINQ. Expressions. Expression <func <tentity, Bool > Predicate );}
To enable the business layer to have irepository and the iextensionrepository interface function, we will create a complete operation interface, which is integrated by the warehousing implementation base class. At the business layer, we can declare
This complete warehousing interface:
/// <Summary> /// Complete data operation Interfaces /// The complete interface includes two events. /// </Summary> Public Interface Icompleterepository <t> : Irepository <T> , Iextensionrepository <T> Where T: Class { /// <Summary> /// Occurs after data saved /// </Summary> Event Eventhandler <savedeventargs> Aftersaved; /// <Summary> /// Occurs before data saved /// </Summary> Event Eventhandler <savedeventargs> Beforesaved ;}
A warehousing base class will implement it. Of course, your warehousing base class may have multiple versions depending on the Orm. You can work with IOC to do this dynamically!
Let's look at the diagram of the traditional Dal layer: (I prefer the DDD architecture, and can still use this traditional architecture for simple businesses)
Well, today's warehousing interface will be discussed here. Haha, the answer to a question may be different in different situations, our architecture should also be flexibly tailored to different business needs, so that we can design a more reasonable architecture!
Young people, you must dare to innovate!