##// END OF EJS Templates
preview version of Unity xml configuration
cin -
r272:9d1cca834b05 v3
parent child
Show More
@@ -0,0 +1,119
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Linq;
5 using System.Xml.Serialization;
6 using Implab.Xml;
7 using Unity.Injection;
8 using Unity.Registration;
9
10 namespace Implab.ServiceHost.Unity {
11 class RegistrationContext {
12 readonly TypeResolver m_resolver;
13
14 List<InjectionMember> m_injections = new List<InjectionMember>();
15
16 Type m_defaultType;
17
18 public Type RegistrationType {
19 get;
20 private set;
21 }
22
23 public Type ImplementationType {
24 get;
25 private set;
26 }
27
28 public RegistrationContext(TypeResolver resolver, string typeSpec, string implSpec) {
29 RegistrationType = resolver.Resolve(string.IsNullOrEmpty(typeSpec) ? implSpec : typeSpec);
30
31
32 ImplementationType = string.IsNullOrEmpty(implSpec) ? RegistrationType : resolver.Resolve(implSpec);
33
34 if (RegistrationType.IsGenericTypeDefinition) {
35 m_resolver = new TypeResolver(resolver);
36
37 foreach (var p in ImplementationType.GetGenericArguments())
38 m_resolver.AddMapping(p.Name, p);
39 } else {
40 m_resolver = resolver;
41 }
42
43
44 }
45
46 public InjectionMember[] Injections {
47 get {
48 return m_injections.ToArray();
49 }
50 }
51
52 public void Visit(ConstructorInjectionElement constructorInjection) {
53 var parameters = constructorInjection.Parameters?.Select(x => x.Resolve(this)).ToArray();
54
55 var injection = parameters != null ? new InjectionConstructor(parameters) : new InjectionConstructor();
56 m_injections.Add(injection);
57 }
58
59 public void Visit(MethodInjectionElement methodInjection) {
60 var parameters = methodInjection.Parameters?.Select(x => x.Resolve(this)).ToArray();
61
62 var injection = parameters != null ? new InjectionMethod(methodInjection.Name, parameters) : new InjectionMethod(methodInjection.Name);
63 m_injections.Add(injection);
64 }
65
66 public void Visit(PropertyInjectionElement propertyInjection) {
67 if (propertyInjection.Value == null)
68 throw new Exception($"A value value must be specified for the property '{propertyInjection.Name}'");
69
70 try {
71 m_defaultType = RegistrationType.GetProperty(propertyInjection.Name)?.PropertyType;
72
73 var parameter = propertyInjection.Value.Resolve(this);
74 var injection = new InjectionProperty(propertyInjection.Name, parameter);
75 m_injections.Add(injection);
76
77 } finally {
78 m_defaultType = null;
79 }
80
81 }
82
83 Type ResolveParameterType(InjectionParameterElement injectionParameter) {
84 if (string.IsNullOrEmpty(injectionParameter.TypeName)) {
85 if (m_defaultType == null)
86 throw new Exception($"A type must be specified for the parameter {injectionParameter}");
87 return m_defaultType;
88 }
89 return m_resolver.Resolve(injectionParameter.TypeName);
90 }
91
92 public object Resolve(DefaultParameterElement defaultParameter) {
93 var type = ResolveParameterType(defaultParameter);
94
95 return Safe.CreateDefaultValue(type);
96 }
97
98 public object Resolve(ValueParameterElement valueParameter) {
99 var type = ResolveParameterType(valueParameter);
100
101 return TypeDescriptor.GetConverter(type).ConvertFromString(valueParameter.Value);
102 }
103
104 public object Resolve(SerializedParameterElement serializedParameter) {
105 var type = ResolveParameterType(serializedParameter);
106 if (serializedParameter.Content == null || serializedParameter.Content.Length == 0)
107 return Safe.CreateDefaultValue(type);
108
109 var serializer = new XmlSerializer(type);
110 using (var reader = serializedParameter.Content[0].CreateNavigator().ReadSubtree())
111 return serializer.Deserialize(reader);
112 }
113
114 public InjectionParameterValue Resolve(DependencyParameterElement dependencyParameter) {
115 var type = ResolveParameterType(dependencyParameter);
116 return new ResolvedParameter(type, dependencyParameter.DependencyName);
117 }
118 }
119 } No newline at end of file
@@ -1,58 +1,86
1 1 using System;
2 2 using System.Diagnostics;
3 using System.Linq;
3 4 using Implab.Diagnostics;
4 5 using Implab.ServiceHost.Unity;
5 6 using Implab.Xml;
6 7 using Unity;
7 8 using Unity.Injection;
9 using Unity.Registration;
8 10
9 11 namespace Implab.Playground {
10 12
11 13 public class Foo {
12 14
13 15 public class Bar {
14 16
15 17 }
16 18
17 19 public string Name { get; set; }
18 20
19 21 public int IntValue { get; set; }
20 22
21 23 public string StringValue { get; set; }
22 24
23 25 }
24 26
25 public class Container<T> {
27 public interface IContainer<T> {
28 T Instance { get; set; }
29 }
30
31 public class Container<T> : IContainer<T> {
26 32 public Container() {
27 33
28 34 }
29 35
30 36 public Container(T instance) {
31 37 Instance = instance;
32 38 }
33 39
34 40 public T Instance { get; set; }
35 41
36 42 public void SetInstance(T value) {
37 43 Instance = value;
38 44 }
39 45 }
40 46
41 47 public class Program {
42 48
43 49 static void Main(string[] args) {
44 50 var container = new UnityContainer();
45 51
46 52 var ctx = new ConfigurationContext(container);
47 53
48 54 var conf = SerializationHelpers.DeserializeFromFile<ContainerElement>("data/sample.xml");
49 55
50 56 ctx.Visit(conf);
51 57
52 Console.WriteLine($"Registrations: {conf.Items.Count}");
58 DisplayContainerRegistrations(container);
59
60 var instace1 = container.Resolve<IContainer<string>>();
61 var instace2 = container.Resolve<IContainer<Foo>>();
62
63 }
53 64
65 static void DisplayContainerRegistrations(IUnityContainer theContainer) {
66 string regName, regType, mapTo, lifetime;
67 Console.WriteLine("Container has {0} Registrations:",
68 theContainer.Registrations.Count());
69 foreach (ContainerRegistration item in theContainer.Registrations) {
70 regType = item.RegisteredType.FullName;
71 mapTo = item.MappedToType.FullName;
72 regName = item.Name ?? "[default]";
73 lifetime = item.LifetimeManager.LifetimeType.Name;
74 if (mapTo != regType) {
75 mapTo = " -> " + mapTo;
76 } else {
77 mapTo = string.Empty;
78 }
79 lifetime = lifetime.Substring(0, lifetime.Length - "LifetimeManager".Length);
80 Console.WriteLine("+ {0}{1} '{2}' {3}", regType, mapTo, regName, lifetime);
81 }
54 82 }
55 83
56 84
57 85 }
58 86 }
@@ -1,38 +1,40
1 1 <?xml version="1.0" encoding="UTF-8"?>
2 2 <container xmlns="http://implab.org/schemas/servicehost/unity.v1.xsd">
3 <namespace name="System"/>
3 4 <namespace name="Implab.Playground"/>
4 5
5 6 <!-- foo1 -->
6 7 <register name="foo1" type="Foo">
7 8 <property name="Name">
8 9 <value>FOO!</value>
9 10 </property>
10 11 </register>
11 12
12 13 <!-- foo2 -->
13 14 <register name="foo2" type="Foo">
14 15 <property name="Name">
15 16 <value>GOOD</value>
16 17 </property>
17 18 <property name="IntValue">
18 19 <value>2</value>
19 20 </property>
20 21 </register>
21 22
22 23 <register type="Foo">
23 24 </register>
24 25
25 <register type="Container{}">
26 <register provides="IContainer{}" type="Container{}">
26 27 <constructor/>
27 28 <method name="SetInstance">
28 29 <dependency type="T"/>
29 30 </method>
30 31 </register>
31 32
32 <register type="Container{String}">
33 <property name="Instance">
34 <value>Hello!</value>
35 </property>
33 <register provides="IContainer{String}" type="Container{String}">
34 <constructor/>
35 <method name="SetInstance">
36 <value type="String">Hello!</value>
37 </method>
36 38 </register>
37 39
38 40 </container> No newline at end of file
@@ -1,7 +1,8
1 using System;
2
1 3 namespace Implab.ServiceHost.Unity
2 4 {
3 public abstract class AbstractInjectionElement
4 {
5
5 public abstract class AbstractInjectionElement {
6 internal abstract void Visit(RegistrationContext context);
6 7 }
7 8 } No newline at end of file
@@ -1,34 +1,32
1 1 using System;
2 2 using System.Xml.Serialization;
3 3 using Unity.Lifetime;
4 4 using Unity.Registration;
5 5
6 6 namespace Implab.ServiceHost.Unity
7 7 {
8 8 public abstract class AbstractRegistration : IConfigurationElement {
9 9
10 10 /// <summary>
11 11 /// An optional name for a registration in the container
12 12 /// </summary>
13 13 [XmlAttribute("name")]
14 14 public string Name {
15 15 get; set;
16 16 }
17 17
18 18 [XmlElement("signleton", typeof(SimgletonLifetimeElement))]
19 19 [XmlElement("context", typeof(ContextLifetimeElement))]
20 20 [XmlElement("container", typeof(ContainerLifetimeElement))]
21 21 [XmlElement("hierarchy", typeof(HierarchicalLifetimeElement))]
22 22 public LifetimeElement Lifetime {get; set;}
23 23
24 24 /// <summary>
25 25 /// A type specification for the service registration,
26 26 /// </summary>
27 27 [XmlAttribute("provides")]
28 28 public string ProvidesType { get; set; }
29 29
30 public void Visit(ConfigurationContext context) {
31 context.Visit(this);
32 }
30 public abstract void Visit(ConfigurationContext context);
33 31 }
34 32 } No newline at end of file
@@ -1,64 +1,78
1 1 using System;
2 2 using System.Collections.Generic;
3 3 using System.Text.RegularExpressions;
4 4 using Implab.Diagnostics;
5 5
6 6 namespace Implab.ServiceHost.Unity {
7 7 using System.Linq;
8 8 using System.Reflection;
9 9 using System.Text;
10 10 using global::Unity;
11 using global::Unity.Registration;
11 12 using Implab.Xml;
12 13 using static Trace<ConfigurationContext>;
13 14
14 15 public class ConfigurationContext {
15 16
16 17 readonly TypeResolver m_resolver;
17 18
18
19
20 19 readonly UnityContainer m_container;
21 20
22 21 public ConfigurationContext(UnityContainer container) {
23 22 m_container = container ?? new UnityContainer();
24 23 m_resolver = new TypeResolver();
25 24 }
26 25
27 26
28 27 public Type Resolve(string typeReference) {
29 28 return m_resolver.Resolve(TypeReference.Parse(typeReference));
30 29 }
31 30
32 internal void Visit(AbstractRegistration descriptor) {
31 internal void Visit(RegisterElement descriptor) {
32 var registrationContext = new RegistrationContext(m_resolver, descriptor.ProvidesType, descriptor.ImplementationType);
33
34 if (descriptor.Injectors != null) {
35 foreach (var injector in descriptor.Injectors) {
36 injector.Visit(registrationContext);
37 }
38 }
39
40 m_container.RegisterType(
41 registrationContext.RegistrationType,
42 registrationContext.ImplementationType,
43 descriptor.Name,
44 descriptor.Lifetime?.GetLifetimeManager(this),
45 registrationContext.Injections
46 );
33 47
34 48 }
35 49
36 50 internal void Visit(NamespaceElement namespaceElement) {
37 51 m_resolver.AddNamespace(namespaceElement.Name);
38 52 }
39 53
40 54 internal void Visit(AssemblyElement assemblyElement) {
41 55 Assembly.Load(assemblyElement.AssemblyName);
42 56 }
43 57
44 58 internal void Visit(IncludeElement includeElement) {
45 59 Include(includeElement.Href);
46 60 }
47 61
48 62 public void Include(string file) {
49 63 var includeContext = new ConfigurationContext(m_container);
50 64 includeContext.LoadConfig(file);
51 65 }
52 66
53 67 public void LoadConfig(string file) {
54 68 var config = SerializationHelpers.DeserializeFromFile<ContainerElement>(file);
55 69 Visit(config);
56 70 }
57 71
58 72 public void Visit(ContainerElement containerElement) {
59 73 foreach (var item in containerElement.Items)
60 74 item.Visit(this);
61 75 }
62 76
63 77 }
64 78 } No newline at end of file
@@ -1,12 +1,16
1 1 using System.Xml.Serialization;
2 2
3 3 namespace Implab.ServiceHost.Unity {
4 4 public class ConstructorInjectionElement : AbstractInjectionElement {
5 5
6 6 [XmlElement("dependency", typeof(DependencyParameterElement))]
7 7 [XmlElement("value", typeof(ValueParameterElement))]
8 8 [XmlElement("serialized", typeof(SerializedParameterElement))]
9 9 [XmlElement("default", typeof(DefaultParameterElement))]
10 10 public InjectionParameterElement[] Parameters { get; set; }
11
12 internal override void Visit(RegistrationContext context) {
13 context.Visit(this);
14 }
11 15 }
12 16 } No newline at end of file
@@ -1,7 +1,8
1 1 namespace Implab.ServiceHost.Unity
2 2 {
3 public class DefaultParameterElement : InjectionParameterElement
4 {
5
3 public class DefaultParameterElement : InjectionParameterElement {
4 internal override object Resolve(RegistrationContext context) {
5 return context.Resolve(this);
6 }
6 7 }
7 8 } No newline at end of file
@@ -1,7 +1,16
1 namespace Implab.ServiceHost.Unity
2 {
3 public class DependencyParameterElement : InjectionParameterElement
4 {
1 using System.Xml.Serialization;
2
3 namespace Implab.ServiceHost.Unity {
4 public class DependencyParameterElement : InjectionParameterElement {
5 5
6 [XmlAttribute("name")]
7 public string DependencyName { get; set; }
8
9 [XmlAttribute("optional")]
10 public bool Optional { get; set; }
11
12 internal override object Resolve(RegistrationContext context) {
13 return context.Resolve(this);
14 }
6 15 }
7 16 } No newline at end of file
@@ -1,9 +1,11
1 1 using System.Xml.Serialization;
2 2
3 3 namespace Implab.ServiceHost.Unity {
4 public class InjectionParameterElement {
4 public abstract class InjectionParameterElement {
5 5
6 6 [XmlAttribute("type")]
7 7 public string TypeName { get; set; }
8
9 internal abstract object Resolve(RegistrationContext context);
8 10 }
9 11 } No newline at end of file
@@ -1,16 +1,19
1 1 using System.Xml.Serialization;
2 2
3 3 namespace Implab.ServiceHost.Unity {
4 4 public class MethodInjectionElement : AbstractInjectionElement {
5 5
6 6 [XmlAttribute("name")]
7 7 public string Name { get; set; }
8 8
9 9 [XmlElement("dependency", typeof(DependencyParameterElement))]
10 10 [XmlElement("value", typeof(ValueParameterElement))]
11 11 [XmlElement("serialized", typeof(SerializedParameterElement))]
12 12 [XmlElement("default", typeof(DefaultParameterElement))]
13 13 public InjectionParameterElement[] Parameters { get; set; }
14 14
15 internal override void Visit(RegistrationContext context) {
16 context.Visit(this);
17 }
15 18 }
16 19 } No newline at end of file
@@ -1,12 +1,19
1 1 using System.Xml.Serialization;
2 2
3 3 namespace Implab.ServiceHost.Unity {
4 4 public class PropertyInjectionElement : AbstractInjectionElement {
5 5
6 [XmlAttribute("name")]
7 public string Name { get; set; }
8
6 9 [XmlElement("dependency", typeof(DependencyParameterElement))]
7 10 [XmlElement("value", typeof(ValueParameterElement))]
8 11 [XmlElement("serialized", typeof(SerializedParameterElement))]
9 12 [XmlElement("default", typeof(DefaultParameterElement))]
10 13 public InjectionParameterElement Value { get; set; }
14
15 internal override void Visit(RegistrationContext context) {
16 context.Visit(this);
17 }
11 18 }
12 19 } No newline at end of file
@@ -1,24 +1,28
1 1 using System;
2 2 using System.Xml.Serialization;
3 3 using Unity.Lifetime;
4 4 using Unity.Registration;
5 5
6 6 namespace Implab.ServiceHost.Unity {
7 7
8 8 [XmlRoot("register", Namespace = Schema.ContainerConfigurationNamespace)]
9 9 public class RegisterElement : AbstractRegistration {
10 10
11 11 /// <summary>
12 12 /// An optional type which is registered as a service in the container, must be assignable to <see cref="ProvidesType">.
13 13 /// </summary>
14 14 [XmlAttribute("type")]
15 public string ImplementedType { get; set; }
15 public string ImplementationType { get; set; }
16 16
17 17
18 18 [XmlElement("constructor", typeof(ConstructorInjectionElement))]
19 19 [XmlElement("property", typeof(PropertyInjectionElement))]
20 20 [XmlElement("method", typeof(MethodInjectionElement))]
21 21 public AbstractInjectionElement[] Injectors { get; set; }
22
23 public override void Visit(ConfigurationContext context) {
24 context.Visit(this);
25 }
22 26 }
23 27
24 28 } No newline at end of file
@@ -1,12 +1,16
1 1 using System.Xml;
2 2 using System.Xml.Schema;
3 3 using System.Xml.Serialization;
4 4
5 5 namespace Implab.ServiceHost.Unity
6 6 {
7 7 public class SerializedParameterElement : InjectionParameterElement {
8 8
9 9 [XmlAnyElement]
10 10 public XmlElement[] Content { get; set; }
11
12 internal override object Resolve(RegistrationContext context) {
13 return context.Resolve(this);
14 }
11 15 }
12 16 } No newline at end of file
@@ -1,124 +1,129
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 Implab.Diagnostics;
7 7
8 8 namespace Implab.ServiceHost.Unity
9 9 {
10 10 using static Trace<TypeResolver>;
11 11 public class TypeResolver
12 12 {
13 13 readonly Dictionary<string, Type> m_cache = new Dictionary<string, Type>();
14 14
15 15 Regex _nsRx = new Regex(@"^\w+(\.\w+)*$", RegexOptions.Compiled);
16 16 readonly LinkedList<string> m_namespases = new LinkedList<string>();
17 17
18 18 LinkedListNode<string> m_insertAt;
19 19
20 20 readonly TypeResolver m_parent;
21 21
22 22 public TypeResolver() : this(null) {
23 23
24 24 }
25 25
26 26 public TypeResolver(TypeResolver parent) {
27 m_parent = parent;
27 28 m_insertAt = new LinkedListNode<string>(string.Empty);
28 29 m_namespases.AddFirst(m_insertAt);
29 30 }
30 31
31 32 public void AddNamespace(string ns) {
32 33 Safe.ArgumentMatch(ns, nameof(ns), _nsRx);
33 34 if (m_insertAt != null)
34 35 m_namespases.AddAfter(m_insertAt, ns);
35 36 else
36 37 m_namespases.AddFirst(ns);
37 38 }
38 39
39 40 public void AddMapping(string typeName, Type type) {
40 41 Safe.ArgumentNotEmpty(typeName, nameof(typeName));
41 42 Safe.ArgumentNotNull(type, nameof(type));
42 43
43 44 m_cache[typeName] = type;
44 45 }
45 46
46 47 public Type Resolve(TypeReference reference) {
47 48 var args = reference.IsGeneric && !reference.IsOpenGeneric ? reference.GenericParameters?.Select(Resolve).ToArray() : null;
48 49 var argc = reference.IsGeneric ? reference.GenericParameters.Length : 0;
49 50
50 51 Type resolved;
51 52 if(!m_cache.TryGetValue(reference.ToString(), out resolved)) {
52 53 resolved = ResolveInternal(reference, args, argc);
53 54 if (resolved == null)
54 55 throw new Exception($"Failed to resolve {reference}");
55 56 m_cache[reference.ToString()] = resolved;
56 57 }
57 58
58 59 return resolved;
59 60 }
60 61
62 public Type Resolve(string typeSpec) {
63 return Resolve(TypeReference.Parse(typeSpec));
64 }
65
61 66 Type ResolveInternal(TypeReference reference, Type[] args, int argc) {
62 67 var resolved = ProbeInNamespaces(
63 68 String.Join(".", new [] { reference.Namespace, reference.TypeName }.Where(x => !string.IsNullOrEmpty(x)) ),
64 69 args,
65 70 argc,
66 71 reference.IsArray,
67 72 reference.ToString()
68 73 );
69 74
70 75 if (resolved == null && m_parent != null)
71 76 resolved = m_parent.Resolve(reference);
72 77
73 78 return resolved;
74 79 }
75 80
76 81 public Type ProbeInNamespaces(string localName, Type[] args, int argc, bool isArray, string referenceName) {
77 82 foreach (var ns in m_namespases) {
78 83 var typeName = FormatName(new [] { ns, localName}, argc, args, isArray);
79 84
80 85 var resolved = Probe(typeName);
81 86 if (resolved != null) {
82 87 Log("Probe succeed {0} in '{1}': {2} -> {3}", referenceName, ns, typeName, resolved.AssemblyQualifiedName);
83 88 return resolved;
84 89 } else {
85 90 Log("Probe failed {0} in '{1}': {2}", referenceName, ns, typeName);
86 91 }
87 92 }
88 93
89 94 return null;
90 95 }
91 96
92 97 Type Probe(string typeName) {
93 98 var assemblies = AppDomain.CurrentDomain.GetAssemblies();
94 99
95 100 foreach(var assembly in assemblies) {
96 101 var type = assembly.GetType(typeName);
97 102 if (type != null)
98 103 return type;
99 104 }
100 105 return null;
101 106 }
102 107
103 108 string FormatName(string[] parts, int argc, Type[] args, bool isArray) {
104 109 var builder = new StringBuilder();
105 110
106 111 builder.Append(String.Join(".", parts.Where(x => !string.IsNullOrEmpty(x))));
107 112 if (argc > 0) {
108 113 builder.Append('`');
109 114 builder.Append(argc);
110 115 }
111 116
112 117 if (args!= null && args.Length > 0) {
113 118 builder.Append('[');
114 119 builder.Append(string.Join(",", args.Select(x => $"[{x.AssemblyQualifiedName}]")));
115 120 builder.Append(']');
116 121 }
117 122
118 123 if(isArray)
119 124 builder.Append("[]");
120 125
121 126 return builder.ToString();
122 127 }
123 128 }
124 129 } No newline at end of file
@@ -1,7 +1,14
1 using System.Xml.Serialization;
2
1 3 namespace Implab.ServiceHost.Unity
2 4 {
3 5 public class ValueParameterElement : InjectionParameterElement
4 6 {
7 [XmlText]
8 public string Value { get; set; }
5 9
10 internal override object Resolve(RegistrationContext context) {
11 return context.Resolve(this);
12 }
6 13 }
7 14 } No newline at end of file
@@ -1,182 +1,189
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 public static object CreateDefaultValue(Type type) {
59 if (type.IsValueType)
60 return Activator.CreateInstance(type);
61
62 return null;
63 }
64
58 65 [MethodImpl(MethodImplOptions.AggressiveInlining)]
59 66 public static void ArgumentInRange(bool condition, string paramName) {
60 67 if (!condition)
61 68 throw new ArgumentOutOfRangeException(paramName);
62 69 }
63 70
64 71 [MethodImpl(MethodImplOptions.AggressiveInlining)]
65 72 public static void ArgumentOfType(object value, Type type, string paramName) {
66 73 if (!type.IsInstanceOfType(value))
67 74 throw new ArgumentException(String.Format("The parameter must be of type {0}", type), paramName);
68 75 }
69 76
70 77 public static void Dispose(params IDisposable[] objects) {
71 78 foreach (var d in objects)
72 79 if (d != null)
73 80 d.Dispose();
74 81 }
75 82
76 83 public static void Dispose(params object[] objects) {
77 84 foreach (var obj in objects) {
78 85 var d = obj as IDisposable;
79 86 if (d != null)
80 87 d.Dispose();
81 88 }
82 89 }
83 90
84 91 public static void DisposeCollection(IEnumerable<IDisposable> objects) {
85 92 foreach (var d in objects)
86 93 Dispose(d);
87 94 }
88 95
89 96 public static void DisposeCollection(IEnumerable objects) {
90 97 foreach (var d in objects)
91 98 Dispose(d);
92 99 }
93 100
94 101 public static void Dispose(object obj) {
95 102 if (obj is IDisposable)
96 103 Dispose((IDisposable)obj);
97 104
98 105 }
99 106
100 107 [DebuggerStepThrough]
101 108 public static void DispatchEvent<T>(this EventHandler<T> handler, object sender, T args) {
102 109 if (handler != null)
103 110 handler(sender, args);
104 111 }
105 112
106 113 [DebuggerStepThrough]
107 114 public static void DispatchEvent(this EventHandler handler, object sender, EventArgs args) {
108 115 if (handler != null)
109 116 handler(sender, args);
110 117 }
111 118
112 119 [DebuggerStepThrough]
113 120 public static IPromise<T> Run<T>(Func<T> action) {
114 121 ArgumentNotNull(action, "action");
115 122
116 123 try {
117 124 return Promise.Resolve(action());
118 125 } catch (Exception err) {
119 126 return Promise.Reject<T>(err);
120 127 }
121 128 }
122 129
123 130 [DebuggerStepThrough]
124 131 public static IPromise Run(Action action) {
125 132 ArgumentNotNull(action, "action");
126 133
127 134 try {
128 135 action();
129 136 return Promise.Resolve();
130 137 } catch (Exception err) {
131 138 return Promise.Reject(err);
132 139 }
133 140 }
134 141
135 142 [DebuggerStepThrough]
136 143 public static IPromise Run(Func<IPromise> action) {
137 144 ArgumentNotNull(action, "action");
138 145
139 146 try {
140 147 return action() ?? Promise.Reject(new Exception("The action returned null"));
141 148 } catch (Exception err) {
142 149 return Promise.Reject(err);
143 150 }
144 151 }
145 152
146 153 public static void NoWait(IPromise promise) {
147 154 }
148 155
149 156 public static void NoWait(Task promise) {
150 157 }
151 158
152 159 public static void NoWait<T>(Task<T> promise) {
153 160 }
154 161
155 162 public static void Noop() {
156 163 }
157 164
158 165 public static void Noop(CancellationToken ct) {
159 166 ct.ThrowIfCancellationRequested();
160 167 }
161 168
162 169 public static Task CreateTask() {
163 170 return new Task(Noop);
164 171 }
165 172
166 173 public static Task CreateTask(CancellationToken ct) {
167 174 return new Task(Noop, ct);
168 175 }
169 176
170 177 [DebuggerStepThrough]
171 178 public static IPromise<T> Run<T>(Func<IPromise<T>> action) {
172 179 ArgumentNotNull(action, "action");
173 180
174 181 try {
175 182 return action() ?? Promise.Reject<T>(new Exception("The action returned null"));
176 183 } catch (Exception err) {
177 184 return Promise.Reject<T>(err);
178 185 }
179 186 }
180 187
181 188 }
182 189 }
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