This is where I use the CloudXplorer tool.
1. Take a snapshot of the disk (while the VM is stopped)
3. Use CloudXplorer to promote the snapshot after breaking the disk lease.
4. Use CloudXplorer to (re)acquire the lease.
A layered application consists of three principal layers: presentation, domain and data source.
The presentation layer is about the interaction between the user and the application, while the data source layer for most applications consists of a relational database and the logic needed to read and write data in the database.
The domain layer contains the domain logic, also referred to as business logic. This is the work the application needs to do. It is important to notice that each layer has its own responsibilities and that communication between the layers must occur via well-defined interfaces.
The domain layer can be subdivided into a Domain Model and Service sub-layer depending on the complexity of the application and the patterns used to implement the domain logic.
The domain logic can use the following patterns:
· Transaction Script
· Domain Model
· Table Module
DTO is an enterprise design pattern to implement the interface between the presentation and the domain layer.
Using DTO’s assures that the domain model (and possibly the domain logic) is not exposed to the presentation layer. Although the use of this pattern is certainly not advocated by Microsoft .NET tooling and Microsoft example code, it is imho a necessary pattern to achieve the needed separation between the presentation and the domain layer.
The discussion whether or not to use DTO’s is out of the scope of this document as there are pro’s and con’s for each approach.
Advantages of DTO’s:
· Isolation of logic
· SOA requirement
· Reduced number of remote calls
· Improved performance
· Testablility
· Deterministic content
Disadvantages of DTO’s:
· Possible class explosion
· Additional computing
· Additional code effort
Most of the disadvantages can be resolved by code generation of the DTO’s and the associated mappers between the DTO’s and the domain entities. Additional computing is in most remote scenario’s (presentation layer is remote) not an issue because serialization of more complex domain entities will require more computing than serializing the simple DTO structures.
How to use DTO’s efficiently is the subject of this document.
Following figure shows the packages and dependencies in a layered application.
The domain model is the heart of the application. It contains the domain entities and the repository interface definitions. By defining the repository interfaces, the domain model describes the operations it requires to bring entities in memory and persist entities to the database. The business logic is either contained in the domain model (DDD – approach) or in the services when using the Transaction Script pattern. The domain model has no dependencies on any other part of the architecture and is technology agnostic.
The service layer and the data layer have a dependency on the domain model. The data layer because it needs to implement the repositories and handle the persistence of the domain entities. The service layer because it is responsible for orchestrating the business logic.
By defining the repository interfaces in the domain model, the service layer becomes independent of the data layer and is as such independent of the used storage technology. To instantiate the repositories, the service layer uses the inversion of control pattern, eventually accompanied by dependency injection (IoC/DI).
Because the presentation layer should by ignorant of the domain model, it communicates with the service layer using the Data Transfer Object pattern. Since the DTO’s could be shared between the presentation and the service layer (in a .NET only scenario), the DTO’s should not know about the domain entities. In order to map data between the DTO’s and the domain model, mapper or DTO factories must be created in the service layer (because the service layer is the only one that knows both the domain entities and the DTO’s.
Data is delivered to the client in the form of a DTO. This is simplified representation of part of the domain model and is designed to fit the display needs of the client.
If the service would simply use the domain model to retrieve the data and map the needed data from the retrieved entity object graph, way too much data would probably have been retrieved from the database, transported and brought into memory on the application server. We might solve this problem by making the domain model and data layer dependent on the DTOs. But doing this will make it impossible to share the DTOs with the client and will also introduce pollution in the domain model.
Following technique illustrates how we can use LINQ to solve this problem and still retrieve exactly what we need from the database.
We have a database with two tables (Nursery and NurseryPlant) having a one-to-many relation (a Nursery has one or more Plants).
In the domain model this results in two entities (Nursery and NurseryPlant).
When the client needs to display an overview of the Nurseries, it receives a ‘NurseryOverviewResponse’ message containing one or more ‘NurseryOverviewDto’ instances.
The NurseryOverviewDto contains the NurseryId, Usage and Year properties from the Nursery entity and the ForDisplay property which is a calculated property on the DTO (concatenating the other three properties).
The NurseryOverviewDto is produced by code generation and looks as follows:
The same code generator also produced the ‘NurseryOverviewDtoFactory’ type in the service layer.
This type contains mapping function between the Nursery entity and the DTO. It also contains an ‘ExpressionSelector’ which is an LINQ expression that can be used to perform projection in the DTO.
On the repository, following method is defined:
When called from the service implementation, this results in the following query on the database
In this scenario the DTO has a master-detail relationship (Nursery – NurseryPlant).
In order to do the correct projection we need (linked) factories for both types.
Remark that the factory for the master set contains a ‘Queryable<T>’ of the detail set.
The repository is the following:
This results in one query retrieving exactly the needed data from the database.
Using LINQ expressions in the service layer allows us to efficiently populate DTO’s and keep the DTO’s independent from any other component on the server side.
In a next post I will explain how the code generation is implemented.
By default WCF will blow the whistle on applications when they exchange data (by calling a service) that exceeds certain limits imposed by the WCF runtime. These are limits regarding the size of messages, the complexity of the message (such as the number of objects in the object graph), the size of elements in the message and other characteristics of the data exchanged. Exceeding this limits result in the breaking the communication and reporting of this situation as an exception, either on the client or the service side.
WCF is a defensive system, meaning that the limits imposed on the exchanged messaged are deliberately chosen ‘ as small as reasonably’ possible. This is (imho) a healthy approach, especially in the context of public exposed services.
This means that if you run against these limits, the following questions should arise first:
In this series of posts I will discuss the various WCF limits and the ways to change the default settings.
Data contracts are a potential entry point for hackers. One of the types of attacks are ‘Denial of Service’ attacks in which a user sends a vast amount of data to the service so that the service spends most of its time simply trying to receive and read the data and performance suffers accordingly. In order to avoid this type of attacks it is advisable to define messages that cannot contain nested data structures, arrays or collections of indeterminate length. The limits on the message structure are imposed by ‘ReaderQuotas’.
‘ReaderQuotas’ are defined per binding, as such they can be different for each service endpoint. The ‘ReaderQuotas’ are checked by the receiving side (being either the server or the client).
Following quota can be defined:
Internally ‘ReaderQuotas’ apply to the XmlDictionaryReader type used internally to manipulate the soap message.
In configuration file:
1: <system.serviceModel>
2: <bindings>
3: <basicHttpBinding>
4: <binding>
5: <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
6: maxBytesPerRead="4096" maxNameTableCharCount="16384" />
7: </binding>
8: </basicHttpBinding>
9: </bindings>
In code:
Setting the ReaderQuotas in code is not that straightforward because the ReaderQuotas property is not defined on the Binding base class. A little reflection can help as shown in the next example:
1: using (ServiceHost host = new ServiceHost(typeof(TestService), new Uri("http://localhost:80/TestService"), new Uri("net.tcp://localhost:100/TestService")))
2: {
3: host.AddDefaultEndpoints();
4: foreach (ServiceEndpoint endpoint in host.Description.Endpoints)
5: {
6: PropertyInfo propInfo = endpoint.Binding.GetType().GetProperty("ReaderQuotas");
7: if (propInfo != null)
8: {
9: XmlDictionaryReaderQuotas qoutas = propInfo.GetGetMethod().Invoke(endpoint.Binding, null) as XmlDictionaryReaderQuotas;
10: qoutas.MaxBytesPerRead = 10000; // set individual value
11: }
12: }
13: host.Open();
Another option is to derive your own binding type form the WCF provided bindings and tune the ‘ReaderQuotas’ to the desired value.
1: //-----------------------------------------------------------------------
2: // <copyright file="MaximizedNetTcpBinding.cs" company="RealDolmen N.V.">
3: // Copyright (c) RealDolmen. All rights reserved.
4: // </copyright>
5: // <author>Luc Van Keer</author>
6: //-----------------------------------------------------------------------
7: namespace Bromo.TaskChannel
8: {
9: using System;
10: using System.Collections.Generic;
11: using System.Linq;
12: using System.Text;
13: using System.ServiceModel;
14: using System.Xml;
15:
16: public class MaximizedNetTcpBinding : NetTcpBinding
17: {
18: #region Constructors
19:
20: public MaximizedNetTcpBinding()
21: : base()
22: {
23: this.MaximizeSettings();
24: }
25:
26: public MaximizedNetTcpBinding(SecurityMode securityMode)
27: : base(securityMode)
28: {
29: this.MaximizeSettings();
30: }
31:
32: public MaximizedNetTcpBinding(string configurationName)
33: : base(configurationName)
34: {
35: this.MaximizeSettings();
36: }
37:
38: public MaximizedNetTcpBinding(SecurityMode securityMode, bool reliableSessionEnabled)
39: : base(securityMode, reliableSessionEnabled)
40: {
41: this.MaximizeSettings();
42: }
43:
44:
45: #endregion
46:
47: #region Properties
48: #endregion
49:
50: #region Private Methods
51:
52: /// <summary>
53: /// Maximizes the settings.
54: /// </summary>
55: private void MaximizeSettings()
56: {
57: this.ReaderQuotas = XmlDictionaryReaderQuotas.Max;
58: }
59:
60: #endregion
61: }
62: }
The ‘ReaderQuotas’ default values are reasonable values for most services. If you decide to change the defaults, there must be a good reason to do so and the first approach should be to question the design and try to make it operate with the default values.
Following test illustrates the danger of augmenting for example the ‘maxDepth’ value (which at first view might look like a harmless change). This test sends the ‘Employee’ message to the service. The Employee message contains a ‘Manager’ reference to another employee instance. Following graph shows the processor load when performing 500 operation call with a delay of 10msec between each call, sending either a normal 2 level ‘Employee’ structure and a abnormal 1000 level structure.
1: class Singleton {
2: public:
3: static Singleton* Instance();
4: protected:
5: Singleton();
6: private:
7: static Singleton* _instance;
8: };
9: Singleton* Singleton::_instance = 0;
10:
11: Singleton* Singleton::Instance () {
12: if (_instance == 0) {
13: _instance = new Singleton;
14: }
15: return _instance;
16: }
Functionality | MoSCoW | Description |
One instance per application domain | M | Ensures that there is only one instance of the type per application domain. |
Thread-safe construction | M | Construction of the singleton type instance in a multithreaded/multicore environment must also result into one instance per application domain, regardless of any race conditions or compiler/processor optimizations. |
Lazy initialization | S | The actual creation of the type instance is triggered by the first access to the singleton. |
Initialization status indication | C | The possibility to test if the singleton instance has already been created (of course without creating it). |
Re-initialization after exception | C | The possibility to re-trigger the creation of the singleton, should an exception have occurred during the previous attempt to create the instance of the singleton. |
1: public sealed class SingletonApproach1
2: {
3: private readonly static SingletonApproach1 instance;
4:
5: public static SingletonApproach1 Instance
6: {
7: get
8: {
9: return instance;
10: }
11: }
12:
13: static SingletonApproach1()
14: {
15: instance = new SingletonApproach1();
16: }
17:
18: private SingletonApproach1() { }
19:
20: public int P1 { get; set; }
21: }
1: class Program
2: {
3: static void Main(string[] args)
4: {
5: const Int32 iterations = 1000 * 1000 * 1000;
6: PerfTest1(iterations);
7: PerfTest2(iterations);
8: PerfTest1(iterations);
9: Console.ReadLine();
10: }
11: static void PerfTest1(Int32 iterations)
12: {
13: Stopwatch sw = Stopwatch.StartNew();
14: for (Int32 x = 0; x < iterations; x++)
15: {
16: SingletonApproach1.Instance.P1 = 1;
17: }
18: Console.WriteLine("PerfTest1: {0}", sw.Elapsed);
19: }
20: static void PerfTest2(Int32 iterations)
21: {
22: Stopwatch sw = Stopwatch.StartNew();
23: for (Int32 x = 0; x < iterations; x++)
24: {
25: SingletonApproach1.Instance.P1 = 1;
26: }
27: Console.WriteLine("PerfTest2: {0}", sw.Elapsed);
28: }
29: }
PerfTest1: 00:00:03.1461604 PerfTest2: 00:00:00.8905847 PerfTest1: 00:00:03.1043356 |
1: public sealed class SingletonApproach2
2: {
3: private readonly static SingletonApproach2 instance = new SingletonApproach2();
4:
5: public static SingletonApproach2 Instance
6: {
7: get
8: {
9: return instance;
10: }
11: }
12:
13: private SingletonApproach2() { }
14:
15: public int P1 { get; set; }
16: }
|
PerfTest1: 00:00:00.9240271 PerfTest2: 00:00:00.9049068 PerfTest1: 00:00:00.8854748 |
1: public sealed class SingletonApproach2
2: {
3: private readonly static SingletonApproach2 instance = new SingletonApproach2();
4:
5: public static SingletonApproach2 Instance
6: {
7: get
8: {
9: return instance;
10: }
11: }
12:
13: private SingletonApproach2() { Console.WriteLine("Singleton created"); }
14:
15: public int P1 { get; set; }
16: }
17: class Program
18: {
19: static void Main(string[] args)
20: {
21: Do();
22: Console.ReadLine();
23: }
24: static void Do()
25: {
26: Console.WriteLine("About to access the singleton");
27: SingletonApproach2.Instance.P1 = 1;
28: }
29: }
Singleton created About to access the singleton |
1: public sealed class SingletonApproach3
2: {
3: private static SingletonApproach3 instance;
4: private readonly static object synclock = new object();
5:
6: public static SingletonApproach3 Instance
7: {
8: get
9: {
10: lock (synclock)
11: {
12: if (instance == null)
13: {
14: instance = new SingletonApproach3();
15: }
16: return instance;
17: }
18: }
19: }
20:
21: public static bool IsInitialized
22: {
23: get
24: {
25: lock (synclock)
26: {
27: return instance != null;
28: }
29: }
30: }
31:
32: private SingletonApproach3() { }
33:
34: public int P1 { get; set; }
35: }
PerfTest1: 00:01:03.3850922 |
Functionality | MoSCoW | Score |
One instance per application domain | M | |
Thread-safe construction | M | |
Lazy initialization | S | |
Initialization status indication | C | |
Re-initialization after exception | C |
1: public sealed class SingletonApproach4
2: {
3: private static volatile SingletonApproach4 instance;
4: private readonly static object synclock = new object();
5:
6: public static SingletonApproach4 Instance
7: {
8: get
9: {
10: if (instance == null)
11: {
12: lock (synclock)
13: {
14: if (instance == null)
15: {
16: instance = new SingletonApproach4();
17: }
18: }
19: }
20: return instance;
21: }
22: }
23:
24: public static bool IsInitialized
25: {
26: get
27: {
28: lock (synclock)
29: {
30: return instance != null;
31: }
32: }
33: }
34:
35: private SingletonApproach4() { }
36:
37: public int P1 { get; set; }
38: }
PerfTest1: 00:00:14.6866434 |
Functionality | MoSCoW | Score |
One instance per application domain | M | |
Thread-safe construction | M | |
Lazy initialization | S | |
Initialization status indication | C | |
Re-initialization after exception | C |
1: public sealed class SingletonApproach5
2: {
3: public static SingletonApproach5 Instance
4: {
5: get
6: {
7: return Nested.instance;
8: }
9: }
10:
11: private SingletonApproach5() {}
12:
13: class Nested
14: {
15: internal readonly static SingletonApproach5 instance = new SingletonApproach5();
16: static Nested() { }
17: }
18:
19: public int P1 { get; set; }
20: }
Functionality | MoSCoW | Score |
One instance per application domain | M | |
Thread-safe construction | M | |
Lazy initialization | S | |
Initialization status indication | C | |
Re-initialization after exception | C |
Approach | Instantiating method | Non-instantiating method |
1 | 00:00:03.1461604 | 00:00:00.8905847 |
2 | 00:00:00.9240271 | 00:00:00.9049068 |
3 | 00:01:03.3850922 | |
4 | 00:00:14.6866434 | |
5 | 00:00:00.9222056 | 00:00:00.8969283 |
1: public interface IMySingleton
2: {
3: int P1 { get; set; }
4: }
5:
6: public static class Singleton1 : IMySingleton
7: {
8: public static int P1 { get; set; }
9: }
10:
11: public static class Singleton2 : IMySingleton
12: {
13: public static int P1 { get; set; }
14: }
15:
16: class Program
17: {
18: static void Main(string[] args)
19: {
20: DoSomethingWithASingleton(Singleton1);
21: }
22:
23: static void DoSomethingWithASingleton(IMySingleton s)
24: {
25: Console.WriteLine(s.P1);
26: }
27: }
1: public class MySingletonBeforeInit
2: {
3: private readonly static MySingletonBeforeInit instance = new MySingletonBeforeInit();
4: public static MySingletonBeforeInit Current
5: {
6: get { return instance; }
7: }
8: public Guid P1 { get; set; }
9: protected MySingletonBeforeInit()
10: {
11: Console.WriteLine("Creating MySingletonBeforeInit");
12: this.P1 = Guid.NewGuid();
13: }
14: }
15: public class MySingletonDerived1 : MySingletonBeforeInit
16: {
17: private readonly static MySingletonBeforeInit instance = new MySingletonDerived1();
18: public new static MySingletonBeforeInit Current
19: {
20: get { return instance; }
21: }
22: protected MySingletonDerived1() { Console.WriteLine("Creating MySingletonDerived1"); }
23: }
24: public class MySingletonDerived2 : MySingletonBeforeInit
25: {
26: private readonly static MySingletonBeforeInit instance = new MySingletonDerived2();
27: public new static MySingletonBeforeInit Current
28: {
29: get { return instance; }
30: }
31: protected MySingletonDerived2() { Console.WriteLine("Creating MySingletonDerived2"); }
32: }
33: class Program
34: {
35: static void Main(string[] args)
36: {
37: Console.WriteLine(MySingletonDerived1.Current.P1.ToString());
38: Console.WriteLine(MySingletonDerived2.Current.P1.ToString());
39: Console.WriteLine(MySingletonDerived1.Current.P1.ToString());
40: Console.WriteLine(MySingletonDerived2.Current.P1.ToString());
41: Console.ReadLine();
42: }
43: }
Creating MySingletonBeforeInit Creating MySingletonDerived1 Creating MySingletonBeforeInit Creating MySingletonDerived2 07ed6401-131a-45b6-ae57-be6a685c00d9 5bef7ecb-3ccd-4101-a377-e50b93c3af87 07ed6401-131a-45b6-ae57-be6a685c00d9 5bef7ecb-3ccd-4101-a377-e50b93c3af87 |