##// END OF EJS Templates
Fixed Safe.DisposeCollection NullReferenceException...
cin -
r292:807f0bc35f40 v3
parent child
Show More
@@ -1,36 +1,36
1 1 <Project Sdk="Microsoft.NET.Sdk">
2 2
3 3 <PropertyGroup>
4 4 <Authors>Sergey Smirnov</Authors>
5 5 <Title>Implab.ServiceHost</Title>
6 6 <Description>The configurable application host.
7 7 Provides simple and flexible Xml configuration for UnityContainer.
8 8 </Description>
9 9 <Copyright>2012-2018 Sergey Smirnov</Copyright>
10 <Version>1.0.1</Version>
10 <Version>1.0.3</Version>
11 11 <PackageLicenseUrl>https://bitbucket.org/wozard/implabnet/src/v3/Implab/license.txt</PackageLicenseUrl>
12 12 <PackageProjectUrl>https://bitbucket.org/wozard/implabnet</PackageProjectUrl>
13 13 <RepositoryUrl>https://bitbucket.org/wozard/implabnet</RepositoryUrl>
14 14 <RepositoryType>mercurial</RepositoryType>
15 15 <PackageTags>Implab;Xml configuration;IoC;Unity container</PackageTags>
16 16 </PropertyGroup>
17 17
18 18
19 19 <PropertyGroup Condition="'$(OSTYPE)'=='linux'">
20 20 <TargetFrameworks>netcoreapp2.0;net46</TargetFrameworks>
21 21 <FrameworkPathOverride Condition="'$(TargetFramework)'=='net46'">/usr/lib/mono/4.5/</FrameworkPathOverride>
22 22 </PropertyGroup>
23 23
24 24 <PropertyGroup Condition="'$(OSTYPE)'=='windows'">
25 25 <TargetFrameworks>netcoreapp2.0;net46</TargetFrameworks>
26 26 </PropertyGroup>
27 27
28 28 <ItemGroup>
29 29 <PackageReference Include="Unity" Version="5.8.6" />
30 30 </ItemGroup>
31 31
32 32 <ItemGroup>
33 33 <ProjectReference Include="..\Implab\Implab.csproj" />
34 34 </ItemGroup>
35 35
36 36 </Project>
@@ -1,156 +1,161
1 1 using System;
2 2 using System.IO;
3 3 using System.Reflection;
4 4 using Implab.Diagnostics;
5 5 using Unity;
6 6
7 7 namespace Implab.ServiceHost.Unity {
8 8 using Log = Trace<ContainerBuilder>;
9 9
10 10 public class ContainerBuilder {
11 11
12 12 readonly TypeResolver m_resolver;
13 13
14 14 readonly IUnityContainer m_container;
15 15
16 16 readonly ContainerConfigurationSchema m_schema;
17 17
18 18 Uri m_location;
19 19
20 20 public IUnityContainer Container {
21 21 get {
22 22 return m_container;
23 23 }
24 24 }
25 25
26 26 public ContainerBuilder() : this(null, null) {
27 27 }
28 28
29 29 public ContainerBuilder(IUnityContainer container, ContainerConfigurationSchema schema) {
30 30 m_container = container ?? new UnityContainer();
31 31 m_resolver = new TypeResolver();
32 32 m_schema = schema ?? ContainerConfigurationSchema.Default;
33 33 }
34 34
35 35 public Type ResolveType(string typeReference) {
36 36 var resolved = string.IsNullOrEmpty(typeReference) ? null : m_resolver.Resolve(typeReference, true);
37 37 Log.Debug("ResolveType('{0}'): {1}", typeReference, resolved?.FullName);
38 38 return resolved;
39 39 }
40 40
41 41 public void Visit(ITypeRegistration registration) {
42 42 Safe.ArgumentNotNull(registration, nameof(registration));
43 43
44 44 var registrationType = registration.GetRegistrationType(this);
45 45 var implementationType = registration.GetImplementationType(this) ?? registrationType;
46 46
47 47 if (registrationType == null)
48 48 throw new Exception($"A type must be specified for the registration {registration.Name}");
49 49
50 50 var builder = new TypeRegistrationBuilder(
51 51 m_resolver,
52 52 registrationType,
53 53 implementationType,
54 54 this
55 55 );
56 56
57 57 builder.Lifetime = registration.GetLifetime(this);
58 58
59 59 if (registration.MemberInjections != null) {
60 60 foreach(var member in registration.MemberInjections)
61 61 member.Visit(builder);
62 62 }
63 63
64 64 m_container.RegisterType(
65 65 builder.RegistrationType,
66 66 builder.ImplementationType,
67 67 registration.Name,
68 68 builder.Lifetime,
69 69 builder.Injections
70 70 );
71 71 }
72 72
73 73 public void Visit(IInstanceRegistration registration) {
74 74 Safe.ArgumentNotNull(registration, nameof(registration));
75 75
76 76 var registrationType = registration.GetRegistrationType(this);
77 77
78 78 var builder = new InstanceRegistrationBuilder (
79 79 m_resolver,
80 80 registrationType,
81 81 this
82 82 );
83 83
84 84 builder.Lifetime = registration.GetLifetime(this);
85 85
86 86 if (registration.MemberInjections != null) {
87 87 foreach(var member in registration.MemberInjections)
88 88 member.Visit(builder.ValueBuilder);
89 89 }
90 90
91 91 if (builder.RegistrationType == null && builder.ValueBuilder.ValueType == null)
92 92 throw new Exception($"A type must be specified for the registration {registration.Name}");
93 93
94 94 m_container.RegisterInstance(
95 95 builder.RegistrationType ?? builder.ValueBuilder.ValueType,
96 96 registration.Name,
97 97 builder.ValueBuilder.Value,
98 98 builder.Lifetime
99 99 );
100 100 }
101 101
102 102 public void AddNamespace(string ns) {
103 103 m_resolver.AddNamespace(ns);
104 Log.Log($"AddNamespace: {ns}");
104 105 }
105 106
106 107 public void AddAssembly(string assembly) {
107
108 var asm = Assembly.Load(assembly);
109 Log.Log($"AddAssembly: {assembly} -> {asm.FullName}");
108 110 }
109 111
110 112 /// <summary>
111 113 /// Includes the confguration. Creates a new <see cref="ContainerBuilder"/>,
112 114 /// and loads the configuration to it. The created builder will share the
113 115 /// container and will have its own isolated type resolver.
114 116 /// </summary>
115 117 /// <param name="file">A path to configuration relative to the current configuration.</param>
116 118 public void Include(string file) {
117 119 var includeContext = new ContainerBuilder(m_container, m_schema);
118 120
119 121 if (m_location != null) {
120 122 var uri = new Uri(m_location, file);
121 123 includeContext.LoadConfig(uri);
122 124 } else {
123 125 includeContext.LoadConfig(file);
124 126 }
125 127 }
126 128
127 129 /// <summary>
128 130 /// Resolves a path ralatively to the current container configuration location.
129 131 /// </summary>
130 132 /// <param name="location">A path yto resolve</param>
131 133 /// <returns>Resolved Uri fot the specified location</returns>
132 134 public Uri MakeLocationUri(string location) {
133 135 return m_location != null ? new Uri(m_location, location) : new Uri(location);
134 136 }
135 137
136 138 /// <summary>
137 139 /// Loads a configuration from the specified local file.
138 140 /// </summary>
139 141 /// <param name="file">The path to the configuration file.</param>
140 142 public void LoadConfig(string file) {
141 143 Safe.ArgumentNotEmpty(file, nameof(file));
142 144
143 145 LoadConfig(new Uri(Path.GetFullPath(file)));
144 146 }
145 147
146 148 public void LoadConfig(Uri location) {
147 149 Safe.ArgumentNotNull(location, nameof(location));
150
151 Log.Log($"LoadConfig {location}");
152 Safe.ArgumentNotNull(location, nameof(location));
148 153
149 154 m_location = location;
150 155
151 156 var config = m_schema.LoadConfig(location.ToString());
152 157 config.Visit(this);
153 158 }
154 159
155 160 }
156 161 } No newline at end of file
@@ -1,189 +1,193
1 1 using System;
2 2 using System.Collections.Generic;
3 3 using System.Linq;
4 4 using System.Text;
5 5 using System.Text.RegularExpressions;
6 6 using System.Diagnostics;
7 7 using System.Collections;
8 8 using System.Runtime.CompilerServices;
9 9 using System.Threading.Tasks;
10 10 using System.Threading;
11 11
12 12 #if NET_4_5
13 13 using System.Threading.Tasks;
14 14 #endif
15 15
16 16 namespace Implab
17 17 {
18 18 public static class Safe
19 19 {
20 20 [MethodImpl(MethodImplOptions.AggressiveInlining)]
21 21 public static void ArgumentAssert(bool condition, string paramName) {
22 22 if (!condition)
23 23 throw new ArgumentException("The parameter is invalid", paramName);
24 24 }
25 25
26 26 [MethodImpl(MethodImplOptions.AggressiveInlining)]
27 27 public static void ArgumentMatch(string value, string paramName, Regex rx) {
28 28 if (rx == null)
29 29 throw new ArgumentNullException("rx");
30 30 if (!rx.IsMatch(value))
31 31 throw new ArgumentException(String.Format("The prameter value must match {0}", rx), paramName);
32 32 }
33 33
34 34 [MethodImpl(MethodImplOptions.AggressiveInlining)]
35 35 public static void ArgumentNotEmpty(string value, string paramName) {
36 36 if (String.IsNullOrEmpty(value))
37 37 throw new ArgumentException("The parameter can't be empty", paramName);
38 38 }
39 39
40 40 [MethodImpl(MethodImplOptions.AggressiveInlining)]
41 41 public static void ArgumentNotEmpty<T>(T[] value, string paramName) {
42 42 if (value == null || value.Length == 0)
43 43 throw new ArgumentException("The array must be not emty", paramName);
44 44 }
45 45
46 46 [MethodImpl(MethodImplOptions.AggressiveInlining)]
47 47 public static void ArgumentNotNull(object value, string paramName) {
48 48 if (value == null)
49 49 throw new ArgumentNullException(paramName);
50 50 }
51 51
52 52 [MethodImpl(MethodImplOptions.AggressiveInlining)]
53 53 internal static void ArgumentGreaterEqThan(int value, int min, string paramName) {
54 54 if (value < min)
55 55 throw new ArgumentOutOfRangeException(paramName);
56 56 }
57 57
58 58 public static object CreateDefaultValue(Type type) {
59 59 if (type.IsValueType)
60 60 return Activator.CreateInstance(type);
61 61
62 62 return null;
63 63 }
64 64
65 65 [MethodImpl(MethodImplOptions.AggressiveInlining)]
66 66 public static void ArgumentInRange(bool condition, string paramName) {
67 67 if (!condition)
68 68 throw new ArgumentOutOfRangeException(paramName);
69 69 }
70 70
71 71 [MethodImpl(MethodImplOptions.AggressiveInlining)]
72 72 public static void ArgumentOfType(object value, Type type, string paramName) {
73 73 if (!type.IsInstanceOfType(value))
74 74 throw new ArgumentException(String.Format("The parameter must be of type {0}", type), paramName);
75 75 }
76 76
77 77 public static void Dispose(params IDisposable[] objects) {
78 foreach (var d in objects)
79 if (d != null)
80 d.Dispose();
78 if (objects != null)
79 foreach (var d in objects)
80 if (d != null)
81 d.Dispose();
81 82 }
82 83
83 84 public static void Dispose(params object[] objects) {
84 foreach (var obj in objects) {
85 var d = obj as IDisposable;
86 if (d != null)
87 d.Dispose();
88 }
85 if (objects != null)
86 foreach (var obj in objects) {
87 var d = obj as IDisposable;
88 if (d != null)
89 d.Dispose();
90 }
89 91 }
90 92
91 93 public static void DisposeCollection(IEnumerable<IDisposable> objects) {
92 foreach (var d in objects)
93 Dispose(d);
94 if (objects != null)
95 foreach (var d in objects)
96 Dispose(d);
94 97 }
95 98
96 99 public static void DisposeCollection(IEnumerable objects) {
97 foreach (var d in objects)
98 Dispose(d);
100 if (objects != null)
101 foreach (var d in objects)
102 Dispose(d);
99 103 }
100 104
101 105 public static void Dispose(object obj) {
102 106 if (obj is IDisposable)
103 107 Dispose((IDisposable)obj);
104 108
105 109 }
106 110
107 111 [DebuggerStepThrough]
108 112 public static void DispatchEvent<T>(this EventHandler<T> handler, object sender, T args) {
109 113 if (handler != null)
110 114 handler(sender, args);
111 115 }
112 116
113 117 [DebuggerStepThrough]
114 118 public static void DispatchEvent(this EventHandler handler, object sender, EventArgs args) {
115 119 if (handler != null)
116 120 handler(sender, args);
117 121 }
118 122
119 123 [DebuggerStepThrough]
120 124 public static IPromise<T> Run<T>(Func<T> action) {
121 125 ArgumentNotNull(action, "action");
122 126
123 127 try {
124 128 return Promise.Resolve(action());
125 129 } catch (Exception err) {
126 130 return Promise.Reject<T>(err);
127 131 }
128 132 }
129 133
130 134 [DebuggerStepThrough]
131 135 public static IPromise Run(Action action) {
132 136 ArgumentNotNull(action, "action");
133 137
134 138 try {
135 139 action();
136 140 return Promise.Resolve();
137 141 } catch (Exception err) {
138 142 return Promise.Reject(err);
139 143 }
140 144 }
141 145
142 146 [DebuggerStepThrough]
143 147 public static IPromise Run(Func<IPromise> action) {
144 148 ArgumentNotNull(action, "action");
145 149
146 150 try {
147 151 return action() ?? Promise.Reject(new Exception("The action returned null"));
148 152 } catch (Exception err) {
149 153 return Promise.Reject(err);
150 154 }
151 155 }
152 156
153 157 public static void NoWait(IPromise promise) {
154 158 }
155 159
156 160 public static void NoWait(Task promise) {
157 161 }
158 162
159 163 public static void NoWait<T>(Task<T> promise) {
160 164 }
161 165
162 166 public static void Noop() {
163 167 }
164 168
165 169 public static void Noop(CancellationToken ct) {
166 170 ct.ThrowIfCancellationRequested();
167 171 }
168 172
169 173 public static Task CreateTask() {
170 174 return new Task(Noop);
171 175 }
172 176
173 177 public static Task CreateTask(CancellationToken ct) {
174 178 return new Task(Noop, ct);
175 179 }
176 180
177 181 [DebuggerStepThrough]
178 182 public static IPromise<T> Run<T>(Func<IPromise<T>> action) {
179 183 ArgumentNotNull(action, "action");
180 184
181 185 try {
182 186 return action() ?? Promise.Reject<T>(new Exception("The action returned null"));
183 187 } catch (Exception err) {
184 188 return Promise.Reject<T>(err);
185 189 }
186 190 }
187 191
188 192 }
189 193 }
General Comments 3
Under Review
author

Auto status change to "Under Review"

Approved
author

ok, latest stable version should be in default

You need to be logged in to leave comments. Login now