-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSelfComposingInstrument.cs
More file actions
147 lines (138 loc) · 6.53 KB
/
SelfComposingInstrument.cs
File metadata and controls
147 lines (138 loc) · 6.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// =================================================================================================================================
// Copyright (c) RapidField LLC. Licensed under the MIT License. See LICENSE.txt in the project root for license information.
// =================================================================================================================================
using RapidField.SolidInstruments.Core;
using RapidField.SolidInstruments.Core.Concurrency;
using RapidField.SolidInstruments.Core.Extensions;
using System;
using System.Diagnostics;
using System.Threading;
namespace RapidField.SolidInstruments.ObjectComposition
{
/// <summary>
/// Represents an instrument that configures and lazily composes its own dependencies.
/// </summary>
public abstract class SelfComposingInstrument : Instrument
{
/// <summary>
/// Initializes a new instance of the <see cref="SelfComposingInstrument" /> class.
/// </summary>
protected SelfComposingInstrument()
: base()
{
LazyContainer = new Lazy<IObjectContainer>(InitializeContainer, LazyThreadSafetyMode.ExecutionAndPublication);
}
/// <summary>
/// Initializes a new instance of the <see cref="SelfComposingInstrument" /> class.
/// </summary>
/// <param name="stateControlMode">
/// The concurrency control mode that is used to manage state. The default value is
/// <see cref="ConcurrencyControlMode.SingleThreadLock" />.
/// </param>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="stateControlMode" /> is equal to <see cref="ConcurrencyControlMode.Unspecified" />.
/// </exception>
protected SelfComposingInstrument(ConcurrencyControlMode stateControlMode)
: base(stateControlMode)
{
LazyContainer = new Lazy<IObjectContainer>(InitializeContainer, LazyThreadSafetyMode.ExecutionAndPublication);
}
/// <summary>
/// Initializes a new instance of the <see cref="SelfComposingInstrument" /> class.
/// </summary>
/// <param name="stateControlMode">
/// The concurrency control mode that is used to manage state. The default value is
/// <see cref="ConcurrencyControlMode.SingleThreadLock" />.
/// </param>
/// <param name="stateControlTimeoutThreshold">
/// The maximum length of time that the instrument's state control may block a thread before raising an exception, or
/// <see cref="Timeout.InfiniteTimeSpan" /> if indefinite thread blocking is permitted. The default value is
/// <see cref="Timeout.InfiniteTimeSpan" />.
/// </param>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="stateControlMode" /> is equal to <see cref="ConcurrencyControlMode.Unspecified" /> -or-
/// <paramref name="stateControlTimeoutThreshold" /> is less than or equal to <see cref="TimeSpan.Zero" /> and is not equal
/// to <see cref="Timeout.InfiniteTimeSpan" />.
/// </exception>
protected SelfComposingInstrument(ConcurrencyControlMode stateControlMode, TimeSpan stateControlTimeoutThreshold)
: base(stateControlMode, stateControlTimeoutThreshold)
{
LazyContainer = new Lazy<IObjectContainer>(InitializeContainer, LazyThreadSafetyMode.ExecutionAndPublication);
}
/// <summary>
/// Configures and finalizes the object container that produces and manages object instances for the current
/// <see cref="SelfComposingInstrument" />.
/// </summary>
/// <param name="containerBuilder">
/// A builder that is used to configure and finalize the container.
/// </param>
/// <returns>
/// An object container that produces and manages object instances for the current <see cref="SelfComposingInstrument" />.
/// </returns>
protected abstract IObjectContainer BuildContainer(ObjectContainerBuilder containerBuilder);
/// <summary>
/// Releases all resources consumed by the current <see cref="SelfComposingInstrument" />.
/// </summary>
/// <param name="disposing">
/// A value indicating whether or not managed resources should be released.
/// </param>
protected override void Dispose(Boolean disposing)
{
try
{
if (disposing)
{
LazyContainer?.Dispose();
}
}
finally
{
base.Dispose(disposing);
}
}
/// <summary>
/// Initializes a lazily-initializes object container that produces and manages object instances for the current
/// <see cref="SelfComposingInstrument" />.
/// </summary>
/// <returns>
/// A lazily-initializes object container that produces and manages object instances for the current
/// <see cref="SelfComposingInstrument" />.
/// </returns>
/// <exception cref="ObjectBuilderException">
/// An exception was raised while configuring or finalizing the container.
/// </exception>
[DebuggerHidden]
private IObjectContainer InitializeContainer()
{
using (var containerBuilder = new ObjectContainerBuilder())
{
try
{
return BuildContainer(containerBuilder);
}
catch (ObjectBuilderException)
{
throw;
}
catch (Exception exception)
{
throw new ObjectBuilderException(containerBuilder.GetType(), exception);
}
}
}
/// <summary>
/// Gets an object container that produces and manages object instances for the current
/// <see cref="SelfComposingInstrument" />.
/// </summary>
/// <exception cref="ObjectBuilderException">
/// An exception was raised while configuring or finalizing the container.
/// </exception>
protected IObjectContainer Container => LazyContainer.Value;
/// <summary>
/// Represents a lazily-initializes object container that produces and manages object instances for the current
/// <see cref="SelfComposingInstrument" />.
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly Lazy<IObjectContainer> LazyContainer;
}
}