In the previous section we learned the WCF distributed development step for Win (5) service contract and Operation overloading section. Today we will continue to learn about WCF service contract inheritance and service decomposition design-related knowledge points. What are the advantages and disadvantages of WCF service contract inheritance? What are the principles and basis of contract design in actual projects? What is the object-oriented design experience worth learning? Here we will give a detailed introduction. This article first introduces some concepts of contract inheritance in WCF services, example code analysis, and secondly, the design of service contract. The first introduction is also the need for service design, service design principles, sample code analysis. The final part is the summary of the full text. The structure is as follows: "1" oo object-oriented design principles, "2" Service Contract inheritance, "3" service contract decomposition concept, "4" service contract decomposition Principle, "5" Service contract decomposition Code analysis, "6" summary.
"1" Object-oriented design principles OO:
Here we need to review the object-oriented classic design principles first. These design principles have important reference value for the design of our WCF service contract. The service contract actually uses the interface to define the implementation, the syntax is similar, the WCF framework is based on the existing language system, which extends the programming model, such as the addition of property setting mechanism. These design principles will not be difficult to understand if you have been exposed to OO object-oriented concepts. Many programming books will be introduced, design patterns related books will be more detailed introduction. Here are a few key concepts that pave the steps for inheriting and designing the WCF Service contract sections below:
<1> Single Responsibility Principle (SRP): A class should have only one reason to cause it to change.
<2> Open Closure principle (OCP): class modules should be extensible, but not modifiable (open to extensions, closed to changes).
<3>liskov substitution principle (LSP): Subclasses must be able to replace their base classes.
<4> dependency Inversion principle (DIP): High-level modules should not be dependent on lower-layer modules, both of which should be dependent on abstraction. Abstractions should not be dependent on implementation details, and implementation details should be dependent on abstraction.
<5> Interface Isolation principle (ISP): The client program should not be forced to rely on methods that they do not use.
"2" Service Contract Inheritance:
The definition of a service contract is similar to an interface definition, and interfaces can inherit from multiple interfaces. However, WCF contract properties are not supported for inheritance. Because of the problem of the WCF framework itself, the inheritance of contract attributes is not supported, so this gives us a lot of restrictions on the Declaration and use of service contract properties. In the process of using the Contract inheritance property, the waist pay attention to the property inheritance problem of the service-side contract, in addition, after the client adds the service reference, it cannot restore the service-side contract-level relationship, and all the operation contracts are encapsulated by a contract class. So the actual programming we have to take into account two aspects of the situation.
"2.1" service-side contract level:
The interface supports inheritance. But the ServiceContract attribute does not support inheritance, and we look at its implementation code to know inherited = False, that is, inheritance is not supported, and some of the code is as follows:
[AttributeUsage (AttributeTargets.Class | Attributetargets.interface, inherited = False, AllowMultiple = False)]
public sealed class Servicecontractattribute:attribute
{
}
So when defining a multilayer service contract interface, we must tag the ServiceContract attribute on each layer of interfaces to support the WCF service contract properties.
The sample code is as follows:
The contract attribute does not support inheritance, and if it is necessary to inherit the contract attribute, the interface flags the contract attribute and defines a vehicle-based interface contract
[ServiceContract (Namespace = "http://www.cnblogs.com/frank_xl/")]
Interface Ivehicle
{
}
Interface inheritance relationships do not support ServiceContract inheritance
[ServiceContract (Namespace = "http://www.cnblogs.com/frank_xl/")]
Interface Itruck:ivehicle
{
}
The trucking service class is able to implement the entire WCF contract-level interface, where we implement the contract for the run and carry shipments, with the following code:
Truck Service class realizes truck service contract
public class Wcfservicetruck:itruck
{
Ways to implement an interface definition
public string Run ()
{
Console.WriteLine ("Hello!, this an inherite demo");
Return "hello! Truck is running ";
}
Ways to implement an interface definition
public string Carry ()
{
Console.WriteLine ("Hello!, this an inherite demo");
Return "hello! Truck is carrying ";
}
}
The host can expose a separate endpoint for the interface at the bottom of the contract hierarchy, and the configuration file Setup code is as follows:
<service behaviorconfiguration= "Wcfservice.wcfservicebehavior" name= "Wcfservice.wcfservicetruck" >
<endpoint
Address= "Http://localhost:9003/WCFServiceTruck"
Binding= "Wshttpbinding"
contract= "Wcfservice.itruck" >
</endpoint>
<endpoint address= "Mex" binding= "mexHttpBinding" contract= "IMetadataExchange"/>
<baseAddresses>
<add baseaddress= "http://localhost:9003/"/>
</baseAddresses>
</service>
"2.2" Client contract level:
When a client adds a service-side data reference and imports metadata for a service endpoint, the deserialized generated client contract will no longer maintain the original hierarchical relationship. A separate contract named the name of the contract that the endpoint publishes. Contains an operation contract that inherits all the interface definitions in the hierarchy. The action and Responseaction properties in the OperationContract attribute allow you to retain the name of the contract that originally defined each operation. To restore the hierarchical relationship of the service-side contract inheritance, the client can manually modify the proxy and import the definition of the contract to restore the contract hierarchy. The manual recovery method actually gives us a lot of flexibility, but also increases the workload and complexity. The actual project in general contact is not much, here is not detailed introduction, if necessary, can consult the relevant information.
"2.2" Service contract decomposition Concept:
Below we continue to explain some conceptual knowledge of service contract design. In fact, the design of service contract is a more important part in the WCF Distributed Application project. The design and implementation of service contracts is relatively complex, and in addition to paying attention to the existing design principles, it is important to pay attention to WCF contract-related features. Service-oriented analysis and design belong to a relatively new field. The actual service analysis and design we still use the existing experience and principles to refer to our better design of the service contract. This is also why this section presents an object-oriented design principle.
Because the definition of a WCF service contract is based on an existing programming language such as C #, the contract design is actually the design of the service interface first. How should we design the service interface? How do I know what actions should be defined in the service interface? How many operations should each interface contain? And so on are all things that we have to consider. Service contract factoring is to consider the decomposition of the Services interface. In a service-oriented application, the reusable base unit is the service interface. So how to design the service interface is the most serious.
"4" Service contract decomposition Principle:
Here we design the service interface is to follow the principle of single responsibility and interface isolation, but also consider the development cost of the system. A reasonable interface is a professional, loosely coupled, regular, and reusable interface. These advantages are also beneficial to the loose coupling and reusability of the whole system. In general, the purpose of contract decomposition is to make the interface contain fewer operations.
If we define too many fine-grained service interfaces, though they are easy to implement, the cost of integrating them is too high. If we define only a complex service interface, the cost of integration is reduced, but the implementation and maintainability of the interface is poor. When we design a service-oriented system, we need to balance two factors that affect the system, interface costs and integration costs. See.
The cost of a system service is a synthesis of the cost of implementation and the cost of integration. Shows the relationship between the minimum cost and the size and quantity of the service interface. Well-designed system should be in the system integration cost and contract interface design to achieve a balance between the cost, to achieve the overall system development cost reduction.
"5" Service Contract decomposition Code analysis:
Here we explain a simple example of service contract design. Here we also continue to use the bus as an example to explain.
We first define an interface vehicle ivehicle, which defines the following:
[ServiceContract (Namespace = "http://www.cnblogs.com/frank_xl/")]
Interface Ivehicle
{
Contract of operation, running, opening
[OperationContract]
String Run ();
Contract of operation, man-drawn, manned
[OperationContract]
string take ();
Deed of operation, contract of carriage of goods
[OperationContract]
String Carry ();
}
Here the transport interface, respectively defined the run, pull people and cargo three kinds of operation. Placed in an interface. This violates the main principle of interface design in the ISP interface isolation principle. We should not force services to inherit operations that they do not need. Interface Isolation principle ISP: Using multiple specialized interfaces is better than using a single interface. From the point of view of service design, the dependency of one class on another class should be based on the smallest interface. If the service class requires only a few methods, then the service class can inherit the appropriate interface to implement the required methods instead of implementing the unwanted methods. Inheriting an interface means making a commitment, and the service class must be implemented, the so-called contract concept.
Therefore, we break down the service contract into the interface level, through the interface decomposition and inheritance, realize the separation of operations. Here you can redefine the two-interface van Itruck and Coupe icar, respectively, to define their own pull carry (), and the operation of the manned take (), when the service class needs to implement pull operations to avoid the confusion of the interface design responsibilities. The code is as follows:
The contract attribute does not support inheritance, and if it is necessary to inherit the contract attribute, the interface flags the contract attribute and defines a vehicle-based interface contract
[ServiceContract (Namespace = "http://www.cnblogs.com/frank_xl/")]
Interface Ivehicle
{
Contract of operation, running, opening
[OperationContract]
String Run ();
}
Interface inheritance relationships do not support ServiceContract inheritance
[ServiceContract (Namespace = "http://www.cnblogs.com/frank_xl/")]
Interface Itruck:ivehicle
{
Deed of operation, contract of carriage of goods
[OperationContract]
String Carry ();
}
Interface inheritance relationships do not support ServiceContract inheritance
[ServiceContract (Namespace = "http://www.cnblogs.com/frank_xl/")]
Interface Icar:ivehicle
{
Contract of operation, man-drawn, manned
[OperationContract]
string take ();
}
"6" Summary:
The above is a description of the WCF service inheritance and decomposition design knowledge, the following brief introduction:
<1>: This article began to explain OO object-oriented design principles, as a classic face object design experience, but also the design pattern of important knowledge points in the article, the WCF service design has the main reference value, such as the SRP single responsibility, ISP interface isolation and other principles;
<2>: We should avoid designing too many or too few interfaces, consider the complexity of the system's service interface definition and the cost of system service integration. Combine the tradeoffs and get a balance point. The best number of service contract members (based on experience) should be between 3 and 5. Developers should specify a maximum value (for example, 20) when developing a WCF coding specification. This value cannot be exceeded in any case.
Also, avoid defining class attribute operations (Property-like operation) like the property accessors of C #, such as:
[OperationContract]
String Getcarnumber ();
We should not interfere with client property access, when the client calls the abstract operation, does not care about the specific implementation details, is only responsible for invoking the operation, and the service to manage the state of the service object.
<3>:WCF Service Design principle is only a few reference principles, the actual development work to know the role. This includes the classic design principles and design patterns of the face objects described earlier. Actual projects need to combine their own actual situation, real-time adjustment and design of service contract interface design, in order to design a more reasonable and efficient service contract. Finally, the reference code for this article: Files/frank_xl/wcfservicefactoringfrankxulei.rar, the next section we continue to learn the WCF Data Contract knowledge, please continue to focus on ~.
Resources:
1. "Programming WCF Services", by Juval Lowy;
2. Object-oriented design patterns and principles, http://hi.baidu.com/dapengchu/blog/item/0521e6d965525dee38012f5c.html
WCF distributed development step for Win (6): WCF Service contract inheritance and decomposition design