##// END OF EJS Templates
Implab: added XmlDefaultSeializer (SerializersPool is now obsolete)...
cin -
r278:6691aff01de1 v3
parent child
Show More
@@ -0,0 +1,57
1 using System;
2 using System.Text;
3
4 namespace Implab.ServiceHost.Unity {
5 public class ArrayTypeReference : TypeReference {
6 public int Rank { get; private set; }
7
8 public TypeReference ItemsType { get; private set; }
9
10 public override string Name {
11 get {
12 return ItemsType.Name;
13 }
14 }
15
16 public override string ClrName {
17 get {
18 return new StringBuilder()
19 .Append(ItemsType.ClrName)
20 .Append("[")
21 .Append(',', Rank - 1)
22 .Append("]")
23 .ToString();
24 }
25 }
26
27 public override string Namespace {
28 get {
29 return ItemsType.Namespace;
30 }
31 }
32
33 public override int GenericParametersCount {
34 get {
35 return 0;
36 }
37 }
38
39 internal ArrayTypeReference(TypeReference itemsType, int rank) {
40 ItemsType = itemsType;
41 Rank = rank;
42 }
43
44 internal override void Visit(TypeResolutionContext visitor) {
45 visitor.Visit(this);
46 }
47
48 override public string ToString() {
49 return new StringBuilder()
50 .Append(ItemsType.ToString())
51 .Append('[')
52 .Append(',', Rank - 1)
53 .Append(']')
54 .ToString();
55 }
56 }
57 } No newline at end of file
@@ -0,0 +1,29
1 using System;
2
3 namespace Implab.ServiceHost.Unity {
4 public class FactoryActivator : FactoryAbstractRegistratrion {
5
6 public Type FactoryType { get; set; }
7
8 public string FactoryName { get; set; }
9
10 public new Type RegistrationType { get; set; }
11
12 public override void Visit(FactoryRegistrationBuilder builder) {
13 base.Visit(builder);
14
15 builder.GetType()
16 .GetMethod(
17 nameof(FactoryRegistrationBuilder.SetFactoryDependency)
18 , new[] { typeof(string) }
19 )
20 .MakeGenericMethod(FactoryType, RegistrationType)
21 .Invoke(builder, new[] { FactoryName });
22 }
23
24 public override Type GetRegistrationType(Func<string, Type> resolver) {
25 return RegistrationType;
26 }
27
28 }
29 } No newline at end of file
@@ -0,0 +1,72
1 using System;
2 using System.Xml.Serialization;
3 using Implab.Components;
4
5 namespace Implab.ServiceHost.Unity {
6 /// <summary>
7 /// Π Π°ΡΡˆΠΈΡ€ΡΠ΅Ρ‚ ΡΡ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½ΡƒΡŽ Ρ€Π΅Π³ΠΈΡΡ‚Ρ€Π°Ρ†ΠΈΡŽ Ρ‚ΠΈΠΏΠ° Π΄ΠΎ Ρ„Π°Π±Ρ€ΠΈΠΊΠΈ, вмСстС с рСгистрациСй
8 /// самой Ρ„Π°Π±Ρ€ΠΈΠΊΠΈ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ рСгистрации сСрвисов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ½Π° прСдоставляСт.
9 /// </summary>
10 public class FactoryElement : RegisterElement {
11
12 /// <summary>
13 /// Записи ΠΎ сСрвисах, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ Π΄Π°Π½Π½ΠΎΠΉ Ρ„Π°Π±Ρ€ΠΈΠΊΠΎΠΉ.
14 /// </summary>
15 /// <remarks>
16 /// БСрвисы, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΠΊΠ°Π·Π°Π½Ρ‹ Π² рСгистарциях ΠΎΠ½ΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΠ²ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠΌΡƒ,
17 /// Ρ‡Ρ‚ΠΎ Ρ„Π°Π±Ρ€ΠΈΠΊΠ° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚, Π½ΠΎ это остаСтся Π½Π° ΠΎΡ‚ΠΊΡƒΠΏ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π°
18 /// </remarks>
19 [XmlElement("provides")]
20 public ProvidesElement[] Provides { get; set; }
21
22 /// <summary>
23 /// ΠŸΠ΅Ρ€Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅Ρ‚ стандарноС ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ рСгистрации Ρ‚ΠΈΠΏΠ° Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π΅,
24 /// дополняя Π΅Π³ΠΎ рСгистрациСй Ρ„Π°Π±Ρ€ΠΈΡ‡Π½Ρ‹Ρ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² для получСния Ρ‚ΠΈΠΏΠΎΠ².
25 /// </summary>
26 /// <param name="builder">ΠžΠ±ΡŠΠ΅ΠΊΡ‚ для конфигурирования ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π°.</param>
27 public override void Visit(ContainerBuilder builder) {
28 var factoryType = GetRegistrationType(builder.ResolveType);
29
30 base.Visit(builder);
31
32 if (Provides != null && Provides.Length > 0) {
33 // Ссли рСгистрации явно Π·Π°Π΄Π°Π½Ρ‹, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΈΡΡ информация ΠΈΠ· Π½ΠΈΡ…
34 foreach(var item in Provides) {
35 var activator = new FactoryActivator {
36 Name = item.RegistrationName,
37 RegistrationType = builder.ResolveType(item.RegistrationType),
38 FactoryName = Name,
39 FactoryType = factoryType
40 };
41 activator.Visit(builder);
42 }
43 } else {
44 // Ссли рСгистрация явно Π½Π΅ Π·Π°Π΄Π°Π½Π°, Π² качСствС сСрвиса для рСгистрации
45 // ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Ρ‚ΠΈΠΏ создаваСмый Ρ„Π°Π±Ρ€ΠΈΠΊΠΎΠΉ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€
46 // с Ρ‚Π΅ΠΌΠΆΠ΅ ΠΈΠΌΠ΅Π½Π΅ΠΌ, Ρ‡Ρ‚ΠΎ ΠΈ сама Ρ„Π°Π±Ρ€ΠΈΠΊΠ° (Ρ€Π°Π·Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΎΠ΄Π½ΠΎ имя для рСгистрации)
47 var providedType = (
48 factoryType.IsGenericType && factoryType.GetGenericTypeDefinition() == typeof(IFactory<>) ?
49 factoryType :
50 factoryType.GetInterface(typeof(IFactory<>).FullName)
51 )?
52 .GetGenericArguments()[0];
53
54 // Π½Π΅ ΡƒΠ΄Π°Π»ΠΎΡΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅ΠΈΡ‚ΡŒ Ρ‚ΠΈΠΏ
55 if (providedType == null)
56 throw new ArgumentException("Failed to determine a type provided by the factory");
57
58 if (providedType.IsGenericParameter)
59 throw new ArgumentException("Can't register a generic type paramter as a service");
60
61 var activator = new FactoryActivator {
62 Name = Name,
63 RegistrationType = providedType,
64 FactoryName = Name,
65 FactoryType = factoryType
66 };
67
68 activator.Visit(builder);
69 }
70 }
71 }
72 } No newline at end of file
@@ -0,0 +1,5
1 namespace Implab.ServiceHost.Unity {
2 public interface IFactoryMemberInjection {
3 void Visit(FactoryRegistrationBuilder builder);
4 }
5 } No newline at end of file
@@ -0,0 +1,7
1 using System.Collections.Generic;
2
3 namespace Implab.ServiceHost.Unity {
4 public interface IFactoryRegistration : IRegistration {
5 IEnumerable<IFactoryMemberInjection> MemberInjections { get; }
6 }
7 } No newline at end of file
@@ -0,0 +1,5
1 namespace Implab.ServiceHost.Unity {
2 public interface IInjectionParameter {
3 void Visit(InjectionParameterBuilder builder);
4 }
5 } No newline at end of file
@@ -0,0 +1,8
1 using System.Collections.Generic;
2
3 namespace Implab.ServiceHost.Unity {
4 public interface IInstanceRegistration : IRegistration {
5
6 IEnumerable<IInjectionParameter> MemberInjections { get; }
7 }
8 } No newline at end of file
@@ -0,0 +1,12
1 using System;
2 using Unity.Lifetime;
3
4 namespace Implab.ServiceHost.Unity {
5 public interface IRegistration {
6 string Name { get; }
7
8 Type GetRegistrationType(ContainerBuilder builder);
9
10 LifetimeManager GetLifetime(ContainerBuilder builder);
11 }
12 } No newline at end of file
@@ -0,0 +1,6
1 namespace Implab.ServiceHost.Unity
2 {
3 public interface ITypeMemberInjection {
4 void Visit(TypeRegistrationBuilder builder);
5 }
6 } No newline at end of file
@@ -0,0 +1,10
1 using System;
2 using System.Collections.Generic;
3
4 namespace Implab.ServiceHost.Unity {
5 public interface ITypeRegistration : IRegistration {
6 Type GetImplementationType(ContainerBuilder builder);
7
8 IEnumerable<ITypeMemberInjection> MemberInjections { get; }
9 }
10 } No newline at end of file
@@ -0,0 +1,48
1 using System;
2 using System.Text;
3
4 namespace Implab.ServiceHost.Unity {
5 public class NestedTypeReference : TypeReference {
6
7 readonly string m_name;
8
9 readonly int m_genericParametersCount;
10
11 public TypeReference DeclaringType { get; private set; }
12
13 public override string Name {
14 get {
15 return m_name;
16 }
17 }
18
19 public override string Namespace {
20 get {
21 return DeclaringType.Namespace;
22 }
23 }
24
25 public override int GenericParametersCount {
26 get {
27 return m_genericParametersCount;
28 }
29 }
30
31 internal NestedTypeReference(TypeReference declaringType, string name, int parametersCount) {
32 DeclaringType = declaringType;
33 m_name = name;
34 m_genericParametersCount = parametersCount;
35 }
36
37 internal override void Visit(TypeResolutionContext visitor) {
38 visitor.Visit(this);
39 }
40
41 internal override void WriteTypeName(StringBuilder builder) {
42 builder
43 .Append(DeclaringType)
44 .Append('+')
45 .Append(Name);
46 }
47 }
48 } No newline at end of file
@@ -0,0 +1,11
1 using System.Xml.Serialization;
2
3 namespace Implab.ServiceHost.Unity {
4 public class ProvidesElement {
5 [XmlAttribute("type")]
6 public string RegistrationType { get; set; }
7
8 [XmlAttribute("name")]
9 public string RegistrationName { get; set; }
10 }
11 } No newline at end of file
@@ -0,0 +1,36
1 using System;
2
3 namespace Implab.ServiceHost.Unity
4 {
5 public class RootTypeReference : TypeReference {
6 readonly string m_name;
7
8 readonly string m_namespace;
9
10 readonly int m_genericParametersCount;
11
12 public override string Name {
13 get { return m_name; }
14 }
15
16 public override string Namespace {
17 get { return m_namespace; }
18 }
19
20 public override int GenericParametersCount {
21 get { return m_genericParametersCount; }
22 }
23
24 internal RootTypeReference(string ns, string name, int genericParameters) {
25 m_name = name;
26 m_genericParametersCount = genericParameters;
27 m_namespace = ns;
28 }
29
30 internal override void Visit(TypeResolutionContext visitor) {
31 visitor.Visit(this);
32 }
33
34
35 }
36 } No newline at end of file
@@ -0,0 +1,52
1 using System;
2 using System.Linq;
3 using System.Text;
4
5 namespace Implab.ServiceHost.Unity {
6 public class SpecializedTypeReference : TypeReference {
7 public override string Name {
8 get {
9 return GenericType.Name;
10 }
11 }
12
13 public override string Namespace {
14 get {
15 return GenericType.Namespace;
16 }
17 }
18
19 public override int GenericParametersCount {
20 get {
21 return GenericParameters.Length;
22 }
23 }
24
25 public TypeReference GenericType { get; private set; }
26
27 public TypeReference[] GenericParameters { get; private set; }
28
29 internal SpecializedTypeReference(TypeReference genericType, TypeReference[] genericParameters) {
30 GenericType = genericType;
31 GenericParameters = genericParameters;
32 }
33
34 internal override void Visit(TypeResolutionContext visitor) {
35 visitor.Visit(this);
36 }
37
38 internal override void WriteTypeName(StringBuilder builder) {
39 GenericType.WriteTypeName(builder);
40 }
41
42 internal override void WriteTypeParams(StringBuilder builder) {
43 builder.Append('{');
44 for (var i = 0; i < GenericParameters.Length; i++) {
45 if (i > 0)
46 builder.Append(',');
47 builder.Append(GenericParameters[i]);
48 }
49 builder.Append('}');
50 }
51 }
52 } No newline at end of file
@@ -0,0 +1,75
1 using System;
2 using System.Collections.Generic;
3 using Implab.Diagnostics;
4
5 namespace Implab.ServiceHost.Unity {
6 using static Trace<TypeResolver>;
7
8 /// <summary>
9 /// ΠŸΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ‚ ΠΎΠ±ΠΎΠΉΡ‚ΠΈ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ ΠΈ ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ Ρ†Π΅ΠΎΡ‡ΠΊΡƒ ΠΈΠ· Ρ‚ΠΈΠΏΠΎΠ² ΠΈ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² Π³Π΅Π½Π΅Ρ€ΠΈΠΊΠΎΠ², ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ½ΠΈ ΠΏΡ€Π΅Π΄Π»Π°Π³Π°ΡŽΡ‚
10 /// </summary>
11 internal class TypeResolutionContext {
12 readonly TypeResolver m_resolver;
13
14
15 readonly List<Type> m_genericParameters = new List<Type>();
16
17 public IEnumerable<Type> GenericParameters { get { return m_genericParameters; } }
18
19 public Type ResolvedType { get; private set; }
20
21
22 public int ArrayRank { get; private set; }
23
24
25 public bool ThrowOnFail { get; private set; }
26
27 public TypeResolutionContext(TypeResolver resolver, bool throwOnFail) {
28 m_resolver = resolver;
29 ThrowOnFail = throwOnFail;
30 }
31
32 public Type MakeType() {
33 return m_genericParameters.Count > 0 ?
34 ResolvedType?.MakeGenericType(m_genericParameters.ToArray()) :
35 ResolvedType;
36 }
37
38 public void Visit(SpecializedTypeReference typeReference) {
39 typeReference.GenericType.Visit(this);
40
41 if (ResolvedType != null) {
42 foreach (var genericParamRef in typeReference.GenericParameters) {
43 var context = new TypeResolutionContext(m_resolver, ThrowOnFail);
44 genericParamRef.Visit(context);
45 m_genericParameters.Add(context.MakeType());
46 }
47 }
48 }
49
50 public void Visit(NestedTypeReference typeReference) {
51 typeReference.DeclaringType.Visit(this);
52 if (ResolvedType != null)
53 ResolvedType = ResolvedType?.GetNestedType(typeReference.ClrName) ?? Failed(typeReference);
54 }
55
56 public void Visit(RootTypeReference typeReference) {
57 ResolvedType = m_resolver.Resolve(typeReference.Namespace, typeReference.ClrName) ?? Failed(typeReference);
58 }
59
60 public void Visit(ArrayTypeReference typeReference) {
61 var context = new TypeResolutionContext(m_resolver, ThrowOnFail);
62 typeReference.ItemsType.Visit(context);
63 ResolvedType = typeReference.Rank == 1 ?
64 context.MakeType()?.MakeArrayType() :
65 context.MakeType()?.MakeArrayType(typeReference.Rank);
66 }
67
68 Type Failed(TypeReference reference) {
69 Log($"Falied to resolve {reference}");
70 if (ThrowOnFail)
71 throw new Exception($"Failed to resolve {reference}");
72 return null;
73 }
74 }
75 } No newline at end of file
@@ -0,0 +1,14
1 using System.Xml.Serialization;
2 using Implab.Components;
3
4 namespace Implab.Xml {
5 /// <summary>
6 /// This class used to get default serializer for the specified type <typeparamref name="T"/>.
7 /// </summary>
8 /// <typeparam name="T">The type used to create <see cref="XmlSerializer"/></typeparam>
9 public static class XmlDefaultSerializer<T> {
10 static readonly LazyAndWeak<XmlSerializer> m_instance = new LazyAndWeak<XmlSerializer>(() => new XmlSerializer(typeof(T)));
11
12 public static XmlSerializer Instance { get { return m_instance.Value; } }
13 }
14 } No newline at end of file
@@ -0,0 +1,89
1 using System.IO;
2 using System.Text;
3 using System.Xml;
4 using System.Xml.Linq;
5 using System.Xml.Serialization;
6
7 namespace Implab.Xml {
8 public static class XmlSerializerExtensions {
9
10 public static void Serialize(this XmlSerializer that, object obj, XmlElement element) {
11 Safe.ArgumentNotNull(that, nameof(that));
12 using (var writer = element.CreateNavigator().AppendChild())
13 that.Serialize(writer, obj);
14 }
15
16 public static void Serialize(this XmlSerializer that, object obj, XElement element) {
17 Safe.ArgumentNotNull(that, nameof(that));
18 using (var writer = element.CreateWriter())
19 that.Serialize(writer, obj);
20 }
21
22 public static XDocument SerializeAsXDocumnet(this XmlSerializer that, object obj) {
23 Safe.ArgumentNotNull(that, nameof(that));
24 var doc = new XDocument();
25 using (var writer = doc.CreateWriter()) {
26 that.Serialize(writer, obj);
27 }
28 return doc;
29 }
30
31 public static XmlDocument SerializeAsXmlDocument(this XmlSerializer that, object obj) {
32 Safe.ArgumentNotNull(that, nameof(that));
33 var doc = new XmlDocument();
34 using (var writer = doc.CreateNavigator().AppendChild()) {
35 that.Serialize(writer, obj);
36 }
37 return doc;
38 }
39 public static string SerializeAsString(this XmlSerializer that, object obj) {
40 Safe.ArgumentNotNull(that, nameof(that));
41 using (var writer = new StringWriter()) {
42 that.Serialize(writer, obj);
43 return writer.ToString();
44 }
45 }
46
47 public static void SerializeToFile(this XmlSerializer that, object obj, string file, Encoding encoding) {
48 Safe.ArgumentNotNull(that, nameof(that));
49 using (var writer = new StreamWriter(File.Create(file),encoding))
50 that.Serialize(writer, obj);
51 }
52
53 public static void SerializeToFile(this XmlSerializer that, object obj, string file) {
54 SerializeToFile(that, obj, file, Encoding.UTF8);
55 }
56
57 public static object Deserialize(this XmlSerializer that, XmlElement element) {
58 Safe.ArgumentNotNull(that, nameof(that));
59 Safe.ArgumentNotNull(element, nameof(element));
60
61 using (var reader = element.CreateNavigator().ReadSubtree())
62 return that.Deserialize(reader);
63 }
64
65 public static object Deserialize(this XmlSerializer that, XElement element) {
66 Safe.ArgumentNotNull(that, nameof(that));
67 Safe.ArgumentNotNull(element, nameof(element));
68
69 using (var reader = element.CreateReader())
70 return that.Deserialize(reader);
71 }
72
73 public static object DeserializeFromString(this XmlSerializer that, string text) {
74 Safe.ArgumentNotNull(that, nameof(that));
75
76 using(var reader = new StringReader(text))
77 return that.Deserialize(reader);
78 }
79
80 public static object DeserializeFromFile(this XmlSerializer that, string file) {
81 Safe.ArgumentNotNull(that, nameof(that));
82
83 using(var reader = File.OpenRead(file))
84 return that.Deserialize(reader);
85 }
86
87
88 }
89 } No newline at end of file
@@ -2,6 +2,7
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.Diagnostics;
3 using System.Diagnostics;
4 using System.Linq;
4 using System.Linq;
5 using Implab.Components;
5 using Implab.Diagnostics;
6 using Implab.Diagnostics;
6 using Implab.ServiceHost.Unity;
7 using Implab.ServiceHost.Unity;
7 using Implab.Xml;
8 using Implab.Xml;
@@ -29,11 +30,39 namespace Implab.Playground {
29
30
30 }
31 }
31
32
33 public class FooFactory : IFactory<Foo>, IFactory<Foo.Bar> {
34
35 public bool UseSsl { get; set; }
36
37 public string Connection { get; set; }
38
39 public Foo Create() {
40 return new Foo() {
41 Name = "AutoFac"
42 };
43 }
44
45 Foo.Bar IFactory<Foo.Bar>.Create() {
46 return new Foo.Bar();
47 }
48 }
49
32 public interface IContainer<T> {
50 public interface IContainer<T> {
33 T Instance { get; set; }
51 T Instance { get; set; }
34 }
52 }
35
53
36 public class Container<T> : IContainer<T> {
54 public class Container<T> : IContainer<T> {
55 public class Bar {
56
57 }
58
59 public class Bar<T2> {
60 public class Baz {
61
62 }
63
64 }
65
37 public Container() {
66 public Container() {
38
67
39 }
68 }
@@ -65,29 +94,22 namespace Implab.Playground {
65 source.Switch.Level = SourceLevels.All;
94 source.Switch.Level = SourceLevels.All;
66 source.Listeners.Add(listener);
95 source.Listeners.Add(listener);
67
96
68 var stopwatch = new Stopwatch();
97 var resolver = new TypeResolver();
69 stopwatch.Start();
98 resolver.AddNamespace("System");
70
99 resolver.AddNamespace("System.Collections.Generic");
71 var ctx = new ContainerBuilder();
100 resolver.AddNamespace("Implab.Playground");
72
101 resolver.AddMapping("string", typeof(string));
73 Console.WriteLine($"Created: {stopwatch.ElapsedMilliseconds}");
102 resolver.AddMapping("listOf`1", typeof(List<>));
74 stopwatch.Restart();
75
76 ctx.LoadConfig("data/sample.xml");
77
78 Console.WriteLine($"Loaded: {stopwatch.ElapsedMilliseconds}");
79
103
80 var container = ctx.Container;
104 var spec = TypeReference.Parse("Container{listOf{string}}+Bar{List{string}}");
81
105
82 stopwatch.Restart();
106 var t = resolver.Resolve(spec, true);
83 var instace1 = container.Resolve<IContainer<string>>();
84 Console.WriteLine($"Resolved1: {stopwatch.ElapsedMilliseconds}");
85
107
86 stopwatch.Restart();
108 Console.WriteLine("{0}", t);
87 var instace2 = container.Resolve<IContainer<Foo>>();
109 Console.WriteLine("Spec: {0}", spec);
88 Console.WriteLine($"Resolved2: {stopwatch.ElapsedMilliseconds}");
110 Console.WriteLine("IsGenericType: {0}", t.IsGenericType);
89
111 Console.WriteLine("IsGenericTypeDefinition: {0}", t.IsGenericTypeDefinition);
90 DisplayContainerRegistrations(container);
112 Console.WriteLine("ContainsGenericParameters: {0}", t.ContainsGenericParameters);
91 }
113 }
92
114
93 static void DisplayContainerRegistrations(IUnityContainer theContainer) {
115 static void DisplayContainerRegistrations(IUnityContainer theContainer) {
@@ -2,6 +2,7
2 <container xmlns="http://implab.org/schemas/servicehost/unity.v1.xsd">
2 <container xmlns="http://implab.org/schemas/servicehost/unity.v1.xsd">
3 <namespace name="System"/>
3 <namespace name="System"/>
4 <namespace name="System.Collections.Generic"/>
4 <namespace name="System.Collections.Generic"/>
5 <namespace name="Implab.Components"/>
5 <namespace name="Implab.Playground"/>
6 <namespace name="Implab.Playground"/>
6
7
7 <!-- foo1 -->
8 <!-- foo1 -->
@@ -36,7 +37,7
36 </method>
37 </method>
37 <method name="AddRange">
38 <method name="AddRange">
38 <array itemsType="T">
39 <array itemsType="T">
39 <dependency name="foo2"/>
40 <dependency name="foo2-bar"/>
40 </array>
41 </array>
41 </method>
42 </method>
42 </register>
43 </register>
@@ -61,8 +62,13
61 <value name="connection1" type="String"><![CDATA[Connect me <here>!]]></value>
62 <value name="connection1" type="String"><![CDATA[Connect me <here>!]]></value>
62 <value name="name1" type="String" value="Hello!"/>
63 <value name="name1" type="String" value="Hello!"/>
63
64
64 <factory name="foo3" type="FooFactory">
65 <factory name="foo3" type="IFactory{Foo}" mapTo="FooFactory">
65 <parameter name="FooName"><![CDATA[Wired "" objecty <> name @#$%^&]]></parameter>
66 <property name="Connection">
67 <value><![CDATA[Wired "" objecty <> name @#$%^&]]></value>
68 </property>
69 <property name="UseSsl">
70 <value>false</value>
71 </property>
66 </factory>
72 </factory>
67
73
68 </container> No newline at end of file
74 </container>
@@ -13,7 +13,7 namespace Implab.ServiceHost.Unity
13 [XmlElement("default", typeof(DefaultParameterElement))]
13 [XmlElement("default", typeof(DefaultParameterElement))]
14 public InjectionParameterElement[] Items { get; set; }
14 public InjectionParameterElement[] Items { get; set; }
15
15
16 public override void Visit(InjectionValueBuilder builder) {
16 public override void Visit(InjectionParameterBuilder builder) {
17 builder.Visit(this);
17 builder.Visit(this);
18 }
18 }
19 }
19 }
@@ -8,7 +8,7 namespace Implab.ServiceHost.Unity
8 public string AssemblyName { get; set; }
8 public string AssemblyName { get; set; }
9
9
10 public override void Visit(ContainerBuilder builder) {
10 public override void Visit(ContainerBuilder builder) {
11 builder.Visit(this);
11 builder.AddAssembly(AssemblyName);
12 }
12 }
13 }
13 }
14 } No newline at end of file
14 }
@@ -1,17 +1,8
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Reflection;
3 using System.Text.RegularExpressions;
3 using Unity;
4 using Implab.Diagnostics;
5
4
6 namespace Implab.ServiceHost.Unity {
5 namespace Implab.ServiceHost.Unity {
7 using System.Linq;
8 using System.Reflection;
9 using System.Text;
10 using global::Unity;
11 using global::Unity.Registration;
12 using Implab.Xml;
13 using static Trace<ContainerBuilder>;
14
15 public class ContainerBuilder {
6 public class ContainerBuilder {
16
7
17 readonly TypeResolver m_resolver;
8 readonly TypeResolver m_resolver;
@@ -36,7 +27,7 namespace Implab.ServiceHost.Unity {
36 }
27 }
37
28
38 public Type ResolveType(string typeReference) {
29 public Type ResolveType(string typeReference) {
39 return m_resolver.Resolve(typeReference);
30 return m_resolver.Resolve(typeReference, true);
40 }
31 }
41
32
42
33
@@ -91,16 +82,85 namespace Implab.ServiceHost.Unity {
91 );
82 );
92 }
83 }
93
84
94 internal void Visit(NamespaceElement namespaceElement) {
85 public void Visit(ITypeRegistration registration) {
95 m_resolver.AddNamespace(namespaceElement.Name);
86 Safe.ArgumentNotNull(registration, nameof(registration));
87
88 var registrationType = registration.GetRegistrationType(this);
89 var implementationType = registration.GetImplementationType(this) ?? registrationType;
90
91 if (registrationType == null)
92 throw new Exception($"A type must be specified for the registration {registration.Name}");
93
94 var builder = new TypeRegistrationBuilder(
95 m_resolver,
96 registrationType,
97 implementationType
98 );
99
100 builder.Lifetime = registration.GetLifetime(this);
101
102 if (registration.MemberInjections != null) {
103 foreach(var member in registration.MemberInjections)
104 member.Visit(builder);
105 }
106
107 m_container.RegisterType(
108 builder.RegistrationType,
109 builder.ImplementationType,
110 registration.Name,
111 builder.Lifetime,
112 builder.Injections
113 );
96 }
114 }
97
115
98 internal void Visit(AssemblyElement assemblyElement) {
116 public void Visit(IInstanceRegistration registration) {
99 Assembly.Load(assemblyElement.AssemblyName);
117 Safe.ArgumentNotNull(registration, nameof(registration));
118
119 var registrationType = registration.GetRegistrationType(this);
120
121 var builder = new InstanceRegistrationBuilder (
122 m_resolver,
123 registrationType
124 );
125
126 builder.Lifetime = registration.GetLifetime(this);
127
128 if (registration.MemberInjections != null) {
129 foreach(var member in registration.MemberInjections)
130 member.Visit(builder.ValueBuilder);
131 }
132
133 if (builder.RegistrationType == null && builder.ValueBuilder.ValueType == null)
134 throw new Exception($"A type must be specified for the registration {registration.Name}");
135
136 m_container.RegisterInstance(
137 builder.RegistrationType ?? builder.ValueBuilder.ValueType,
138 registration.Name,
139 builder.ValueBuilder.Injection,
140 builder.Lifetime
141 );
100 }
142 }
101
143
102 internal void Visit(IncludeElement includeElement) {
144 public void Visit(IFactoryRegistration registration) {
103 Include(includeElement.Href);
145 Safe.ArgumentNotNull(registration, nameof(registration));
146
147 var registrationType = registration.GetRegistrationType(this);
148
149 var builder = new FactoryRegistrationBuilder(registrationType);
150
151 if (registration.MemberInjections != null) {
152 foreach(var member in registration.MemberInjections)
153 member?.Visit(builder);
154 }
155
156 }
157
158 public void AddNamespace(string ns) {
159 m_resolver.AddNamespace(ns);
160 }
161
162 public void AddAssembly(string assembly) {
163
104 }
164 }
105
165
106 public void Include(string file) {
166 public void Include(string file) {
@@ -110,9 +170,8 namespace Implab.ServiceHost.Unity {
110
170
111 public void LoadConfig(string file) {
171 public void LoadConfig(string file) {
112 var config = m_schema.LoadFile(file);
172 var config = m_schema.LoadFile(file);
113
114 config.Visit(this);
173 config.Visit(this);
115 }
174 }
116
175
117 }
176 }
118 } No newline at end of file
177 }
@@ -55,6 +55,7 namespace Implab.ServiceHost.Unity {
55 var schema = new ContainerConfigurationSchema();
55 var schema = new ContainerConfigurationSchema();
56
56
57 schema.RegisterContainerElement<RegisterElement>("register");
57 schema.RegisterContainerElement<RegisterElement>("register");
58 schema.RegisterContainerElement<FactoryElement>("factory");
58 schema.RegisterContainerElement<SerializedElement>("serialized");
59 schema.RegisterContainerElement<SerializedElement>("serialized");
59 schema.RegisterContainerElement<ValueElement>("value");
60 schema.RegisterContainerElement<ValueElement>("value");
60 schema.RegisterContainerElement<IncludeElement>("include");
61 schema.RegisterContainerElement<IncludeElement>("include");
@@ -5,7 +5,7 namespace Implab.ServiceHost.Unity
5 get { return null; }
5 get { return null; }
6 }
6 }
7
7
8 public override void Visit(InjectionValueBuilder builder) {
8 public override void Visit(InjectionParameterBuilder builder) {
9 var type = builder.ResolveInjectedValueType(TypeName);
9 var type = builder.ResolveInjectedValueType(TypeName);
10 builder.SetValue(type, Safe.CreateDefaultValue(type));
10 builder.SetValue(type, Safe.CreateDefaultValue(type));
11 }
11 }
@@ -9,7 +9,7 namespace Implab.ServiceHost.Unity {
9 [XmlAttribute("optional")]
9 [XmlAttribute("optional")]
10 public bool Optional { get; set; }
10 public bool Optional { get; set; }
11
11
12 public override void Visit(InjectionValueBuilder builder) {
12 public override void Visit(InjectionParameterBuilder builder) {
13 var type = builder.ResolveInjectedValueType(TypeName);
13 var type = builder.ResolveInjectedValueType(TypeName);
14 builder.SetDependencyReference(type, DependencyName, Optional);
14 builder.SetDependencyReference(type, DependencyName, Optional);
15 }
15 }
@@ -13,12 +13,25 namespace Implab.ServiceHost.Unity
13 internal FactoryRegistrationBuilder(Type registrationType) : base(registrationType) {
13 internal FactoryRegistrationBuilder(Type registrationType) : base(registrationType) {
14 }
14 }
15
15
16 /// <summary>
17 /// Π—Π°Π΄Π°Π΅Ρ‚ Π΄Π΅Π»Π΅Π³Π°Ρ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π² качСствС Ρ„Π°Π±Ρ€ΠΈΠΊΠΈ
18 /// для создания экзСмпляров, ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Π΄Π΅Π»Π°Π³Π°Ρ‚Π° Π±ΡƒΠ΄Π΅Ρ‚ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Ρ‹
19 /// ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌΠΈ зависимостями.
20 /// </summary>
21 /// <param name="factory">Π€Π°Π±Ρ€ΠΈΠΊΠ° для создания экзСмпляров.</param>
16 public void SetFactoryDelegate(Delegate factory) {
22 public void SetFactoryDelegate(Delegate factory) {
17 Safe.ArgumentNotNull(factory, nameof(factory));
23 Safe.ArgumentNotNull(factory, nameof(factory));
18
24
19 Factory = new DelegateInjectionFactory(factory);
25 Factory = new DelegateInjectionFactory(factory);
20 }
26 }
21
27
28 /// <summary>
29 /// Π£ΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ Ρ‚ΠΈΠΏΠ° <typeparamref name="T"/> с ΠΈΠΌΠ΅Π½Π΅ΠΌ
30 /// <paramref name="dependencyName"/>, которая Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π° Π² ΠΊΠ°Ρ‡Π΅Ρ‚Π²Π΅
31 /// ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Π΄Π΅Π»Π΅Π³Π°Ρ‚Ρƒ <paramref name="factory"/>
32 /// </summary>
33 /// <param name="dependencyName">Имя зависимости</param>
34 /// <param name="factory">Π€Π°Π±Ρ€ΠΈΠΊΠ° для создания экзСмпляра</param>
22 public void SetFactoryDependency<T>(string dependencyName, Func<T, object> factory) {
35 public void SetFactoryDependency<T>(string dependencyName, Func<T, object> factory) {
23 Safe.ArgumentNotNull(factory, nameof(factory));
36 Safe.ArgumentNotNull(factory, nameof(factory));
24
37
@@ -28,6 +41,11 namespace Implab.ServiceHost.Unity
28 });
41 });
29 }
42 }
30
43
44 /// <summary>
45 /// Π£ΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ‚ΡŒ, Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‰ΡƒΡŽ интСрфСйс <see cref="IFactory{TObj}"/>,
46 /// которая Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π² качСствС Ρ„Π°Π±Ρ€ΠΈΠΊΠΈ для создания ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²
47 /// </summary>
48 /// <param name="dependencyName"></param>
31 public void SetFactoryDependency<TFac, TObj>(string dependencyName) where TFac : IFactory<TObj> {
49 public void SetFactoryDependency<TFac, TObj>(string dependencyName) where TFac : IFactory<TObj> {
32
50
33 Factory = new InjectionFactory(c => c.Resolve<TFac>(dependencyName).Create());
51 Factory = new InjectionFactory(c => c.Resolve<TFac>(dependencyName).Create());
@@ -6,8 +6,8 namespace Implab.ServiceHost.Unity {
6 [XmlAttribute("href")]
6 [XmlAttribute("href")]
7 public string Href { get; set; }
7 public string Href { get; set; }
8
8
9 public override void Visit(ContainerBuilder context) {
9 public override void Visit(ContainerBuilder builder) {
10 context.Visit(this);
10 builder.Include(Href);
11 }
11 }
12 }
12 }
13 } No newline at end of file
13 }
@@ -7,6 +7,6 namespace Implab.ServiceHost.Unity {
7 [XmlAttribute("type")]
7 [XmlAttribute("type")]
8 public string TypeName { get; set; }
8 public string TypeName { get; set; }
9
9
10 public abstract void Visit(InjectionValueBuilder builder);
10 public abstract void Visit(InjectionParameterBuilder builder);
11 }
11 }
12 } No newline at end of file
12 }
@@ -7,7 +7,7 using Unity.Injection;
7
7
8 namespace Implab.ServiceHost.Unity {
8 namespace Implab.ServiceHost.Unity {
9
9
10 public class InjectionValueBuilder {
10 public class InjectionParameterBuilder {
11
11
12 readonly TypeResolver m_resolver;
12 readonly TypeResolver m_resolver;
13
13
@@ -26,7 +26,7 namespace Implab.ServiceHost.Unity {
26 }
26 }
27 }
27 }
28
28
29 internal InjectionValueBuilder(TypeResolver resolver, Type defaultType) {
29 internal InjectionParameterBuilder(TypeResolver resolver, Type defaultType) {
30 m_resolver = resolver;
30 m_resolver = resolver;
31 DefaultType = defaultType;
31 DefaultType = defaultType;
32 }
32 }
@@ -37,11 +37,11 namespace Implab.ServiceHost.Unity {
37 throw new Exception("The type must be specified");
37 throw new Exception("The type must be specified");
38 return DefaultType;
38 return DefaultType;
39 }
39 }
40 return m_resolver.Resolve(typeSpec);
40 return m_resolver.Resolve(typeSpec, true);
41 }
41 }
42
42
43 public Type ResolveType(string typeSpec) {
43 public Type ResolveType(string typeSpec) {
44 return m_resolver.Resolve(typeSpec);
44 return m_resolver.Resolve(typeSpec, true);
45 }
45 }
46
46
47 public void SetValue(Type type, object value) {
47 public void SetValue(Type type, object value) {
@@ -75,13 +75,16 namespace Implab.ServiceHost.Unity {
75
75
76 InjectionParameterValue[] injections = (arrayParameter.Items ?? new InjectionParameterElement[0])
76 InjectionParameterValue[] injections = (arrayParameter.Items ?? new InjectionParameterElement[0])
77 .Select(x => {
77 .Select(x => {
78 var builder = new InjectionValueBuilder(m_resolver, itemsType);
78 var builder = new InjectionParameterBuilder(m_resolver, itemsType);
79 x.Visit(builder);
79 x.Visit(builder);
80 return builder.Injection;
80 return builder.Injection;
81 })
81 })
82 .ToArray();
82 .ToArray();
83
83
84 var array = itemsType.IsGenericParameter ? (object)new GenericResolvedArrayParameter(itemsType.Name, injections) : new ResolvedArrayParameter(itemsType, injections);
84 var array = itemsType.IsGenericParameter ?
85 (object)new GenericResolvedArrayParameter(itemsType.Name, injections) :
86 new ResolvedArrayParameter(itemsType, injections);
87
85 ValueType = arrayType;
88 ValueType = arrayType;
86 Value = array;
89 Value = array;
87 }
90 }
@@ -4,10 +4,10 namespace Implab.ServiceHost.Unity
4 {
4 {
5 public class InstanceRegistrationBuilder : RegistrationBuilder {
5 public class InstanceRegistrationBuilder : RegistrationBuilder {
6
6
7 public InjectionValueBuilder ValueBuilder { get; private set; }
7 public InjectionParameterBuilder ValueBuilder { get; private set; }
8
8
9 internal InstanceRegistrationBuilder(TypeResolver typeResolver, Type registrationType) : base(registrationType) {
9 internal InstanceRegistrationBuilder(TypeResolver typeResolver, Type registrationType) : base(registrationType) {
10 ValueBuilder = new InjectionValueBuilder(typeResolver, registrationType);
10 ValueBuilder = new InjectionParameterBuilder(typeResolver, registrationType);
11 }
11 }
12 }
12 }
13 } No newline at end of file
13 }
@@ -8,8 +8,8 namespace Implab.ServiceHost.Unity
8 [XmlAttribute("name")]
8 [XmlAttribute("name")]
9 public string Name { get; set; }
9 public string Name { get; set; }
10
10
11 public override void Visit(ContainerBuilder context) {
11 public override void Visit(ContainerBuilder builder) {
12 context.Visit(this);
12 builder.AddNamespace(Name);
13 }
13 }
14 }
14 }
15 } No newline at end of file
15 }
@@ -21,7 +21,7 namespace Implab.ServiceHost.Unity
21 throw new Exception("No content found, expected XML document");
21 throw new Exception("No content found, expected XML document");
22 }
22 }
23
23
24 public override void Visit(InjectionValueBuilder builder) {
24 public override void Visit(InjectionParameterBuilder builder) {
25 var type = builder.ResolveInjectedValueType(TypeName);
25 var type = builder.ResolveInjectedValueType(TypeName);
26
26
27 var serializer = new XmlSerializer(type);
27 var serializer = new XmlSerializer(type);
@@ -3,56 +3,180 using System.Linq;
3 using System.Text;
3 using System.Text;
4
4
5 namespace Implab.ServiceHost.Unity {
5 namespace Implab.ServiceHost.Unity {
6 public class TypeReference {
6 /// <summary>
7 public string TypeName { get; set; }
7 /// Бсылка Π½Π° Ρ‚ΠΈΠΏ, являСтся абстрактной записью ΠΈΠΌΠ΅Π½ΠΈ CLR Ρ‚ΠΈΠΏΠ°.
8
8 /// </summary>
9 public string Namespace { get; set; }
9 /// <remarks>
10
10 /// Бсылка Π½Π° Ρ‚ΠΈΠΏ содСрТит ΡΠΎΠΊΡ€Π°Ρ‰Π΅Π½Π½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ Ρ‚ΠΈΠΏΠ΅ ΠΈ для Π΅Π΅ ΠΈΠ½Ρ‚Π΅Ρ€ΠΏΡ€Π΅Ρ‚Π°Ρ†ΠΈΠΈ
11 public TypeReference[] GenericParameters { get; set; }
11 /// трСбуСтся Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ контСкст, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ ΠΏΡ€Π΅Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ Π΅Π΅ Π² ΠΏΠΎΠ»Π½ΠΎΡ†Π΅Π½Π½Ρ‹ΠΉ
12
12 /// <see cref="Type"/>. Бсылки Π½Π° Ρ‚ΠΈΠΏ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ:
13 public bool IsArray { get; set; }
13 /// <list>
14 /// <item><description>ΠΎΠ±Ρ‰ΠΈΠ΅ Ρ‚ΠΈΠΏΡ‹, ΠΈΡ… спСциализации</description></item>
15 /// <item><description>Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹</description></item>
16 /// <item><description>массивы</description></item>
17 /// </list>
18 /// <para>
19 /// Для получСния ΠΈΠ· ссылки Π½Π° Ρ‚ΠΈΠΏ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ CLR Ρ‚ΠΈΠΏΠ° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ <see cref="TypeResolver.Resolve(TypeReference, bool)"/>.
20 /// </para>
21 /// <para>
22 /// Бсылку Π½Π° Ρ‚ΠΈΠΏ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π»ΠΈΠ±ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ½ΠΎ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² <see cref="Create(string, string, int)"/>,
23 /// <see cref="Create(string, int)"/>, <see cref="MakeArrayType(int)"/>, <see cref="MakeGenericType(TypeReference[])"/>,
24 /// Π»ΠΈΠ±ΠΎ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Π² строку со спСцификациСй ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° <see cref="Parse(string)"/>.
25 /// </para>
26 /// <para>
27 /// БпСцификация ссыдки Π½Π° Ρ‚ΠΈΠΏ ΠΈΠΌΠ΅Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π²ΠΈΠ΄ <c>Name.Space.MyType+Nested{String}[][]</c>, Π³Π΄Π΅:
28 /// <list type="table">
29 /// <item>
30 /// <term><c>.</c></term>
31 /// <description>РаздСляСт элСмСнты пространства ΠΈΠΌΠ΅Π½</description>
32 /// <item>
33 /// <item>
34 /// <term><c>+</c></term>
35 /// <description>РаздСляСт Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹</description>
36 /// <item>
37 /// <item>
38 /// <term><c>[]</c>, <c>[,,,]</c></term>
39 /// <description>Π£ΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Ρ‚ΠΈΠΏ являСтся массивом, Ρ‚Π°ΠΊΠΆΠ΅ указываСтся Π΅Π³ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Π½ΠΎΡΡ‚ΡŒ</description>
40 /// <item>
41 /// <item>
42 /// <term><c>{}</c>, <c>{,,}</c>, <c>{Int32,String}</c></term>
43 /// <description>Π£ΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Ρ‚ΠΈΠΏ являСтся ΠΎΠ±Ρ‰ΠΈΠΌ, Ρ‚Π°ΠΊΠΆΠ΅
44 /// указываСтся количСство ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ², Π»ΠΈΠ±ΠΎ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ для
45 /// спСциализации</description>
46 /// <item>
47 /// </list>
48 /// </para>
49 /// </remarks>
50 public abstract class TypeReference {
14
51
15 public bool IsOpenGeneric {
52 /// <summary>
53 /// Имя Ρ‚ΠΈΠΏΠ° Π±Π΅Π· Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… элСмСнтов, ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΡ… Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ ΠΎΠ±Ρ‰ΠΈΠΉ ΠΈΠ»ΠΈ массив.
54 /// </summary>
55 /// <remarks>
56 /// Для массивов это имя Π΅Π³ΠΎ элСмСнтов.
57 /// </remarks>
58 public abstract string Name { get; }
59
60 /// <summary>
61 /// ΠŸΡ€ΠΎΡΡ‚Ρ€Π°Π½ΡΡ‚Π²ΠΎ ΠΈΠΌΠ΅Π½ Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ нахоТится Ρ‚ΠΈΠΏ.
62 /// </summary>
63 /// <remarks>
64 /// Для Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² это пространтство ΠΈΠΌΠ΅Π½ Ρ‚ΠΈΠΏΠ° самого Π²Π΅Ρ€Ρ…Π½Π΅Π³ΠΎ уровня,
65 /// для массивов - пространство ΠΈΠΌΠ΅Π½ Π΅Π³ΠΎ элСмСнтов.
66 /// </remarks>
67 public abstract string Namespace { get; }
68
69 /// <summary>
70 /// ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΎΠ±Ρ‰Π΅Π³ΠΎ Ρ‚ΠΈΠΏΠ°.
71 /// </summary>
72 /// <remarks>
73 /// <para>
74 /// Π’Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ нСявно ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‚ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΎΡ‚ Ρ‚ΠΈΠΏΠΎΠ² Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΎΠ½ΠΈ ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Ρ‹,
75 /// Π΄Π°Π½Π½ΠΎΠ΅ свойство это Π½Π΅ ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°Π΅Ρ‚, возвращаСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ количСство собствСнных
76 /// ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ².
77 /// </para>
78 /// <para>
79 /// Π”Π°Π½Π½ΠΎΠ΅ свойство ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для получСния CRL ΠΈΠΌΠ΅Π½ΠΈ Ρ‚ΠΈΠΏΠ°.
80 /// </para>
81 /// </remarks>
82 public abstract int GenericParametersCount { get; }
83
84 public virtual string ClrName {
16 get {
85 get {
17 return GenericParameters!=null && GenericParameters.Contains(null);
86 return GenericParametersCount != 0 ? $"{Name}`{GenericParametersCount}" : Name;
18 }
19 }
20
21 public bool IsGeneric {
22 get {
23 return GenericParameters != null && GenericParameters.Length > 0;
24 }
87 }
25 }
88 }
26
89
90 /// <summary>
91 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ ссылку Π½Π° ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ Ρ‚ΠΈΠΏΠ°.
92 /// </summary>
93 /// <param name="genericParameters">Бсылки Π½Π° Ρ‚ΠΈΠΏΡ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ для спСциализации Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ Ρ‚ΠΈΠΏΠ°.</param>
94 /// <returns>БпСциализация Π΄Π°Π½Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°.</returns>
95 public virtual SpecializedTypeReference MakeGenericType(TypeReference[] genericParameters) {
96 if (GenericParametersCount == 0)
97 throw new InvalidOperationException("Can't specialize a non-geneic type");
98
99 if (genericParameters == null || GenericParametersCount != genericParameters.Length)
100 throw new InvalidOperationException("Generic parameters count mismatch");
101
102 return new SpecializedTypeReference(this, genericParameters);
103 }
104
105 /// <summary>
106 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ ссылку Π½Π° Ρ‚ΠΈΠΏ массива ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ размСрности, элСмСнтами ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΡΠ²Π»ΡΡŽΡ‚ΡΡ экзСмпаляры Π΄Π°Π½Π½Π³ΠΎ Ρ‚ΠΈΠΏΠ°.
107 /// </summary>
108 /// <param name="rank">Π Π°Π·ΠΌΠ΅Ρ€Π½ΠΎΡΡ‚ΡŒ, Ссли Ρ€Π°Π·ΠΌΠ΅Ρ€Π½ΠΎΡΡ‚ΡŒ <c>1</c> создаСтся Π²Π΅ΠΊΡ‚ΠΎΡ€ (<see cref="Type.MakeArrayType()"/>).</param>
109 /// <returns>Бсылка Π½Π° Ρ‚ΠΈΠΏ массива</returns>
110 public ArrayTypeReference MakeArrayType(int rank) {
111 Safe.ArgumentInRange(rank > 0, nameof(rank));
112
113 return new ArrayTypeReference(this, rank);
114 }
115
116 /// <summary>
117 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ ссылку Π½Π° Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ Ρ‚ΠΈΠΏ.
118 /// </summary>
119 /// <param name="name">Имя Ρ‚ΠΈΠΏΠ°</param>
120 /// <param name="genericParameters">ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ², Ссли это ΠΎΠ±Ρ‰ΠΈΠΉ Ρ‚ΠΈΠΏ, ΠΈΠ½Π°Ρ‡Π΅ 0.</param>
121 /// <returns>Бсылка Π½Π° Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΉ Ρ‚ΠΈΠΏ.</returns>
122 public TypeReference Create(string name, int genericParameters) {
123 Safe.ArgumentNotEmpty(name, nameof(name));
124 Safe.ArgumentInRange(genericParameters >= 0, nameof(genericParameters));
125
126 return new NestedTypeReference(this, name, genericParameters);
127 }
128
129 /// <summary>
130 /// Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ строковоС прСдставлСниС ссылки Π½Π° Ρ‚ΠΈΠΏ.
131 /// </summary>
132 /// <returns></returns>
27 public override string ToString() {
133 public override string ToString() {
28 var builder = new StringBuilder();
134 var builder = new StringBuilder();
29
135 WriteTypeName(builder);
30 if (!string.IsNullOrEmpty(Namespace)) {
136 WriteTypeParams(builder);
31 builder.Append(Namespace);
32 builder.Append('.');
33 }
34
35 if (!string.IsNullOrEmpty(TypeName)) {
36 builder.Append(TypeName);
37 } else {
38 builder.Append("__unnamed__");
39 }
40
41 if (GenericParameters != null && GenericParameters.Length > 0) {
42 builder.Append('{');
43 for(var i = 0; i < GenericParameters.Length; i++) {
44 if (i > 0)
45 builder.Append(',');
46 builder.Append(GenericParameters[i]);
47 }
48 builder.Append('}');
49 }
50
51 return builder.ToString();
137 return builder.ToString();
52 }
138 }
53 public static TypeReference Parse(string text) {
139
54 var parser = new TypeReferenceParser(text);
140 internal virtual void WriteTypeName(StringBuilder builder) {
141 if (!string.IsNullOrEmpty(Namespace))
142 builder
143 .Append(Namespace)
144 .Append('.');
145 builder.Append(Name);
146 }
147
148 internal virtual void WriteTypeParams(StringBuilder builder) {
149 if (GenericParametersCount > 0)
150 builder
151 .Append('{')
152 .Append(',', GenericParametersCount-1)
153 .Append('}');
154 }
155
156 internal abstract void Visit(TypeResolutionContext visitor);
157
158 /// <summary>
159 /// Π‘ΠΎΠ·Π΄Π°Π΅Ρ‚ ссылку Π½Π° Ρ‚ΠΈΠΏ.
160 /// </summary>
161 /// <param name="ns">ΠŸΡ€ΠΎΡΡ‚Ρ€Π°Π½ΡΡ‚Π²ΠΎ ΠΈΠΌΠ΅Π½, Π»ΠΈΠ±ΠΎ Π΅Π³ΠΎ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚.</param>
162 /// <param name="name">Имя Ρ‚ΠΈΠΏΠ° Π±Π΅Π· указания Π½Π° количСство ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ², Π»ΠΈΠ±ΠΎ Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ это массив.</param>
163 /// <param name="genericParameters">ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² Ρ‚ΠΈΠΏΠ°, Ссли это ΠΎΠ±Ρ‰ΠΈΠΉ Ρ‚ΠΈΠΏ, ΠΈΠ½Π°Ρ‡Π΅ 0.</param>
164 /// <returns>Бсылка Π½Π° Ρ‚ΠΈΠΏ.</returns>
165 public static TypeReference Create(string ns, string name, int genericParameters) {
166 Safe.ArgumentNotEmpty(name, nameof(name));
167 Safe.ArgumentInRange(genericParameters >= 0, nameof(genericParameters));
168 return new RootTypeReference(ns, name, genericParameters);
169 }
170
171 /// <summary>
172 /// Π Π°Π·ΠΈΡ€Π°Π΅Ρ‚ ΡΡ‚Ρ€ΠΎΠΊΠΎΠ²ΡƒΡŽ запись ссылки Π½Π° Ρ‚ΠΈΠΏ.
173 /// </summary>
174 /// <param name="typeSpec">Бтроковая запись ссылки Π½Π° Ρ‚ΠΈΠΏ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ <c>Dictionary{String,String}</c></param>
175 /// <returns>Бсылка Π½Π° Ρ‚ΠΈΠΏ.</returns>
176 public static TypeReference Parse(string typeSpec) {
177 var parser = new TypeReferenceParser(typeSpec);
55 return parser.Parse();
178 return parser.Parse();
56 }
179 }
180
57 }
181 }
58 } No newline at end of file
182 }
@@ -1,5 +1,6
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.Linq;
3 using System.Text.RegularExpressions;
4 using System.Text.RegularExpressions;
4
5
5 namespace Implab.ServiceHost.Unity {
6 namespace Implab.ServiceHost.Unity {
@@ -21,10 +22,12 namespace Implab.ServiceHost.Unity {
21
22
22 CloseArray,
23 CloseArray,
23
24
25 Plus,
26
24 Eof
27 Eof
25 }
28 }
26
29
27 readonly Regex _tokens = new Regex(@"([\w\+]+)|\s*([\.{},\[\]])\s*");
30 readonly Regex _tokens = new Regex(@"\G(?:([\w]+)|\s*([\+\.{},\[\]])\s*)", RegexOptions.Compiled);
28
31
29 TokenType m_token;
32 TokenType m_token;
30
33
@@ -83,6 +86,9 namespace Implab.ServiceHost.Unity {
83 case "]":
86 case "]":
84 m_token = TokenType.CloseArray;
87 m_token = TokenType.CloseArray;
85 break;
88 break;
89 case "+":
90 m_token = TokenType.Plus;
91 break;
86 }
92 }
87 }
93 }
88 return true;
94 return true;
@@ -97,7 +103,7 namespace Implab.ServiceHost.Unity {
97 return result;
103 return result;
98 }
104 }
99
105
100 string[] ReadTypeName() {
106 string[] ReadQTypeName() {
101 var parts = new List<string>();
107 var parts = new List<string>();
102
108
103 string current = null;
109 string current = null;
@@ -129,31 +135,95 namespace Implab.ServiceHost.Unity {
129 return parts.ToArray();
135 return parts.ToArray();
130 }
136 }
131
137
138 string ReadNQTypeName() {
139 ReadToken();
140 if (Token != TokenType.Word)
141 ThrowUnexpectedToken();
142 return TokenValue;
143 }
144
132 TypeReference ReadTypeReference() {
145 TypeReference ReadTypeReference() {
133
146
134 var parts = ReadTypeName();
147 var parts = ReadQTypeName();
135 if (parts == null)
148 if (parts == null)
136 return null;
149 return null;
137
150
138 var typeReference = new TypeReference {
151 var genericParameters = ReadGenericParams();
139 Namespace = string.Join(".", parts, 0, parts.Length - 1),
152
140 TypeName = parts[parts.Length - 1]
153 var typeReference = TypeReference.Create(
141 };
154 string.Join(".", parts, 0, parts.Length - 1),
155 parts[parts.Length - 1],
156 genericParameters.Length
157 );
158
159 if (genericParameters.Length > 0 && genericParameters.All(x => x != null))
160 typeReference = typeReference.MakeGenericType(genericParameters);
161
162 typeReference = ReadArraySpec(typeReference);
163
164 if(Token == TokenType.Plus)
165 return ReadNestedType(typeReference);
166
167 return typeReference;
168 }
169
170 TypeReference ReadNestedType(TypeReference declaringType) {
171 var name = ReadNQTypeName();
172 if(string.IsNullOrEmpty(name))
173 throw new FormatException("Nested type name can't be empty");
174 ReadToken();
175
176 var genericParameters = ReadGenericParams();
177
178 var typeReference = declaringType.Create(
179 name,
180 genericParameters.Length
181 );
142
182
143 switch (Token) {
183 if (genericParameters.Length > 0 && genericParameters.All(x => x != null))
144 case TokenType.OpenList:
184 typeReference = typeReference.MakeGenericType(genericParameters);
145 typeReference.GenericParameters = ReadTypeReferenceList();
185
146 if (Token != TokenType.CloseList)
186 typeReference = ReadArraySpec(typeReference);
147 ThrowUnexpectedToken();
187
148 ReadToken();
188 if(Token == TokenType.Plus)
149 break;
189 return ReadNestedType(typeReference);
190
191 return typeReference;
192 }
193
194 TypeReference[] ReadGenericParams() {
195 if (Token == TokenType.OpenList) {
196 var genericParameters = ReadTypeReferenceList();
197 if (Token != TokenType.CloseList)
198 ThrowUnexpectedToken();
199 ReadToken();
200
201 return genericParameters;
202 }
203
204 return Array.Empty<TypeReference>();
205 }
206
207 TypeReference ReadArraySpec(TypeReference typeReference) {
208 while (Token == TokenType.OpenArray) {
209 var rank = CountRank();
210 if (Token != TokenType.CloseArray)
211 ThrowUnexpectedToken();
212
213 typeReference = typeReference.MakeArrayType(rank);
214
215 ReadToken();
150 }
216 }
151
217
152 return typeReference;
218 return typeReference;
153 }
219 }
154
220
155 int CountDimentions() {
221 int CountRank() {
156 return 0;
222 int rank = 0;
223 do {
224 rank++;
225 } while(ReadToken() && Token == TokenType.Comma);
226 return rank;
157 }
227 }
158
228
159 TypeReference[] ReadTypeReferenceList() {
229 TypeReference[] ReadTypeReferenceList() {
@@ -37,7 +37,7 namespace Implab.ServiceHost.Unity {
37
37
38 var parameters = constructorInjection.Parameters?
38 var parameters = constructorInjection.Parameters?
39 .Select(x => {
39 .Select(x => {
40 var valueBuilder = new InjectionValueBuilder(m_resolver, null);
40 var valueBuilder = new InjectionParameterBuilder(m_resolver, null);
41 x.Visit(valueBuilder);
41 x.Visit(valueBuilder);
42 return valueBuilder.Injection;
42 return valueBuilder.Injection;
43 })
43 })
@@ -48,11 +48,9 namespace Implab.ServiceHost.Unity {
48 }
48 }
49
49
50 internal void Visit(MethodInjectionElement methodInjection) {
50 internal void Visit(MethodInjectionElement methodInjection) {
51 var valueContext = new InjectionValueBuilder(m_resolver, null);
52
53 var parameters = methodInjection.Parameters?
51 var parameters = methodInjection.Parameters?
54 .Select(x => {
52 .Select(x => {
55 var valueBuilder = new InjectionValueBuilder(m_resolver, null);
53 var valueBuilder = new InjectionParameterBuilder(m_resolver, null);
56 x.Visit(valueBuilder);
54 x.Visit(valueBuilder);
57 return valueBuilder.Injection;
55 return valueBuilder.Injection;
58 })
56 })
@@ -66,8 +64,8 namespace Implab.ServiceHost.Unity {
66 if (propertyInjection.Value == null)
64 if (propertyInjection.Value == null)
67 throw new Exception($"A value value must be specified for the property '{propertyInjection.Name}'");
65 throw new Exception($"A value value must be specified for the property '{propertyInjection.Name}'");
68
66
69 var propertyType = RegistrationType.GetProperty(propertyInjection.Name)?.PropertyType;
67 var propertyType = ImplementationType.GetProperty(propertyInjection.Name)?.PropertyType;
70 var valueContext = new InjectionValueBuilder(m_resolver, propertyType);
68 var valueContext = new InjectionParameterBuilder(m_resolver, propertyType);
71
69
72 propertyInjection.Value.Visit(valueContext);
70 propertyInjection.Value.Visit(valueContext);
73 var injection = new InjectionProperty(propertyInjection.Name, valueContext.Injection);
71 var injection = new InjectionProperty(propertyInjection.Name, valueContext.Injection);
@@ -6,6 +6,7 using System.Text.RegularExpressions;
6 using Implab.Diagnostics;
6 using Implab.Diagnostics;
7
7
8 namespace Implab.ServiceHost.Unity {
8 namespace Implab.ServiceHost.Unity {
9 using System.Diagnostics;
9 using static Trace<TypeResolver>;
10 using static Trace<TypeResolver>;
10 public class TypeResolver {
11 public class TypeResolver {
11 readonly Dictionary<string, Type> m_cache = new Dictionary<string, Type>();
12 readonly Dictionary<string, Type> m_cache = new Dictionary<string, Type>();
@@ -13,12 +14,28 namespace Implab.ServiceHost.Unity {
13 Regex _nsRx = new Regex(@"^\w+(\.\w+)*$", RegexOptions.Compiled);
14 Regex _nsRx = new Regex(@"^\w+(\.\w+)*$", RegexOptions.Compiled);
14 readonly LinkedList<string> m_namespases = new LinkedList<string>();
15 readonly LinkedList<string> m_namespases = new LinkedList<string>();
15
16
17 internal Type Resolve(string ns, string typeName) {
18 var fullName = string.IsNullOrEmpty(ns) ? typeName : $"{ns}.{typeName}";
19
20 return ProbeInNamespaces(fullName);
21 }
22
23 public Type Resolve(TypeReference typeReference, bool throwOnFail) {
24 var context = new TypeResolutionContext(this, throwOnFail);
25 typeReference.Visit(context);
26 return context.MakeType();
27 }
28
29 public Type Resolve(string typeSpec, bool throwOnFail) {
30 var typeReference = TypeReference.Parse(typeSpec);
31 return Resolve(typeReference, throwOnFail);
32 }
33
16 LinkedListNode<string> m_insertAt;
34 LinkedListNode<string> m_insertAt;
17
35
18 readonly TypeResolver m_parent;
36 readonly TypeResolver m_parent;
19
37
20 public TypeResolver() : this(null) {
38 public TypeResolver() : this(null) {
21
22 }
39 }
23
40
24 public TypeResolver(TypeResolver parent) {
41 public TypeResolver(TypeResolver parent) {
@@ -42,63 +59,31 namespace Implab.ServiceHost.Unity {
42 m_cache[typeName] = type;
59 m_cache[typeName] = type;
43 }
60 }
44
61
45 public Type Resolve(TypeReference reference) {
62 Type ProbeInNamespaces(string localName) {
46 var args = reference.IsGeneric && !reference.IsOpenGeneric ? reference.GenericParameters?.Select(Resolve).ToArray() : null;
47 var argc = reference.IsGeneric ? reference.GenericParameters.Length : 0;
48
63
49 Type resolved;
64 Type resolved;
50 if (!m_cache.TryGetValue(reference.ToString(), out resolved)) {
65 if (!m_cache.TryGetValue(localName, out resolved)) {
51 resolved = ResolveInternal(reference, args, argc);
66 foreach (var ns in m_namespases) {
52 if (resolved == null)
67 var typeName = string.IsNullOrEmpty(ns) ? localName : $"{ns}.{localName}";
53 throw new Exception($"Failed to resolve {reference}");
68 resolved = Probe(typeName);
54 m_cache[reference.ToString()] = resolved;
69 if (resolved != null) {
70 Log($"Probe '{localName}' -> '{resolved.FullName}'");
71 break;
72 }
73 }
74
75 if (resolved == null && m_parent != null)
76 resolved = m_parent.ProbeInNamespaces(localName);
77
78 if(resolved == null)
79 Log($"Probe '{localName}' failed");
80
81 m_cache[localName] = resolved;
55 }
82 }
56
83
57 return resolved;
84 return resolved;
58 }
85 }
59
86
60 public Type Resolve(string typeSpec) {
61 return Resolve(TypeReference.Parse(typeSpec));
62 }
63
64 Type ResolveInternal(TypeReference reference, Type[] args, int argc) {
65 var resolved = ProbeInNamespaces(
66 String.Join(".", new[] { reference.Namespace, reference.TypeName }.Where(x => !string.IsNullOrEmpty(x))),
67 args,
68 argc,
69 reference.IsArray,
70 reference.ToString()
71 );
72
73 if (resolved == null && m_parent != null)
74 resolved = m_parent.ResolveInternal(reference, args, argc);
75
76 return resolved;
77 }
78
79 public Type ProbeInNamespaces(string localName, Type[] args, int argc, bool isArray, string referenceName) {
80 foreach (var ns in m_namespases) {
81 var typeName = FormatName(new[] { ns, localName }, argc);
82
83 var resolved = Probe(typeName);
84 if (resolved != null) {
85 if (args != null && args.Length > 0) {
86 resolved = resolved.MakeGenericType(args);
87 }
88
89 if (isArray)
90 resolved = resolved.MakeArrayType();
91
92 Log("Probe succeed {0} in '{1}': {2} -> {3}", referenceName, ns, typeName, resolved.AssemblyQualifiedName);
93 return resolved;
94 } else {
95 Log("Probe failed {0} in '{1}': {2}", referenceName, ns, typeName);
96 }
97 }
98
99 return null;
100 }
101
102 Type Probe(string typeName) {
87 Type Probe(string typeName) {
103 var assemblies = AppDomain.CurrentDomain.GetAssemblies();
88 var assemblies = AppDomain.CurrentDomain.GetAssemblies();
104
89
@@ -109,17 +94,5 namespace Implab.ServiceHost.Unity {
109 }
94 }
110 return null;
95 return null;
111 }
96 }
112
113 string FormatName(string[] parts, int argc) {
114 var builder = new StringBuilder();
115
116 builder.Append(String.Join(".", parts.Where(x => !string.IsNullOrEmpty(x))));
117 if (argc > 0) {
118 builder.Append('`');
119 builder.Append(argc);
120 }
121
122 return builder.ToString();
123 }
124 }
97 }
125 } No newline at end of file
98 }
@@ -13,7 +13,7 namespace Implab.ServiceHost.Unity {
13 return string.IsNullOrEmpty(Value) ? Text : Value;
13 return string.IsNullOrEmpty(Value) ? Text : Value;
14 }
14 }
15
15
16 public override void Visit(InjectionValueBuilder builder) {
16 public override void Visit(InjectionParameterBuilder builder) {
17 var type = builder.ResolveInjectedValueType(TypeName);
17 var type = builder.ResolveInjectedValueType(TypeName);
18 builder.SetValue(type, TypeDescriptor.GetConverter(type).ConvertFromString(GetTextValue()));
18 builder.SetValue(type, TypeDescriptor.GetConverter(type).ConvertFromString(GetTextValue()));
19 }
19 }
@@ -12,17 +12,17 using System.Xml.Serialization;
12 namespace Implab.Xml {
12 namespace Implab.Xml {
13 public static class SerializationHelpers {
13 public static class SerializationHelpers {
14 public static string SerializeAsString<T>(T obj) {
14 public static string SerializeAsString<T>(T obj) {
15 return SerializersPool<T>.Instance.SerializeAsString(obj);
15 return XmlDefaultSerializer<T>.Instance.SerializeAsString(obj);
16 }
16 }
17
17
18 public static void Serialize<T>(XmlWriter writer, T obj) {
18 public static void Serialize<T>(XmlWriter writer, T obj) {
19 SerializersPool<T>.Instance.Serialize(writer, obj);
19 XmlDefaultSerializer<T>.Instance.Serialize(writer, obj);
20 }
20 }
21
21
22 public static XmlDocument SerializeAsXmlDocument<T>(T obj) {
22 public static XmlDocument SerializeAsXmlDocument<T>(T obj) {
23 var doc = new XmlDocument();
23 var doc = new XmlDocument();
24 using (var writer = doc.CreateNavigator().AppendChild()) {
24 using (var writer = doc.CreateNavigator().AppendChild()) {
25 SerializersPool<T>.Instance.Serialize(writer, obj);
25 XmlDefaultSerializer<T>.Instance.Serialize(writer, obj);
26 }
26 }
27 return doc;
27 return doc;
28 }
28 }
@@ -30,38 +30,35 namespace Implab.Xml {
30 public static XDocument SerializeAsXDocument<T>(T obj) {
30 public static XDocument SerializeAsXDocument<T>(T obj) {
31 var doc = new XDocument();
31 var doc = new XDocument();
32 using (var writer = doc.CreateWriter()) {
32 using (var writer = doc.CreateWriter()) {
33 SerializersPool<T>.Instance.Serialize(writer, obj);
33 XmlDefaultSerializer<T>.Instance.Serialize(writer, obj);
34 }
34 }
35 return doc;
35 return doc;
36 }
36 }
37
37
38 public static void SerializeToFile<T>(string file, T obj) {
38 public static void SerializeToFile<T>(string file, T obj) {
39 using (var writer = File.CreateText(file))
39 XmlDefaultSerializer<T>.Instance.SerializeToFile(obj, file);
40 SerializersPool<T>.Instance.Serialize(writer, obj);
41 }
40 }
42
41
43 public static void SerializeToElementChild<T>(XmlElement element, T obj) {
42 public static void SerializeToElementChild<T>(XmlElement element, T obj) {
44 using(var writer = element.CreateNavigator().AppendChild())
43 XmlDefaultSerializer<T>.Instance.Serialize(obj, element);
45 SerializersPool<T>.Instance.Serialize(writer, obj);
46 }
44 }
47
45
48 public static T Deserialize<T>(XmlReader reader) {
46 public static T Deserialize<T>(XmlReader reader) {
49 return SerializersPool<T>.Instance.Deserialize(reader);
47 return (T)XmlDefaultSerializer<T>.Instance.Deserialize(reader);
50 }
48 }
51
49
52 public static T DeserializeFromFile<T>(string file) {
50 public static T DeserializeFromFile<T>(string file) {
53 using(var reader = XmlReader.Create(File.OpenText(file)))
51 return (T)XmlDefaultSerializer<T>.Instance.DeserializeFromFile(file);
54 return Deserialize<T>(reader);
55 }
52 }
56
53
57 public static T DeserializeFromString<T>(string data) {
54 public static T DeserializeFromString<T>(string data) {
58 return SerializersPool<T>.Instance.DeserializeFromString(data);
55 return (T)XmlDefaultSerializer<T>.Instance.DeserializeFromString(data);
59 }
56 }
60
57
61 public static T DeserializeFromXmlNode<T>(XmlNode node) {
58 public static T DeserializeFromXmlNode<T>(XmlNode node) {
62 Safe.ArgumentNotNull(node, nameof(node));
59 Safe.ArgumentNotNull(node, nameof(node));
63 using (var reader = node.CreateNavigator().ReadSubtree())
60 using (var reader = node.CreateNavigator().ReadSubtree())
64 return SerializersPool<T>.Instance.Deserialize(reader);
61 return (T)XmlDefaultSerializer<T>.Instance.Deserialize(reader);
65 }
62 }
66
63
67 public static T DeserializeJson<T>(TextReader textReader) {
64 public static T DeserializeJson<T>(TextReader textReader) {
@@ -71,12 +68,12 namespace Implab.Xml {
71 FlattenArrays = true
68 FlattenArrays = true
72 };
69 };
73
70
74 using(var reader = JsonXmlReader.CreateJsonXmlReader(textReader, options))
71 using (var reader = JsonXmlReader.CreateJsonXmlReader(textReader, options))
75 return Deserialize<T>(reader);
72 return Deserialize<T>(reader);
76 }
73 }
77
74
78 public static T DeserializeJsonFromString<T>(string data) {
75 public static T DeserializeJsonFromString<T>(string data) {
79 using(var reader = new StringReader(data)) {
76 using (var reader = new StringReader(data)) {
80 return DeserializeJson<T>(reader);
77 return DeserializeJson<T>(reader);
81 }
78 }
82 }
79 }
@@ -87,7 +84,7 namespace Implab.Xml {
87 }
84 }
88
85
89 public static string SerializeJsonAsString<T>(T obj) {
86 public static string SerializeJsonAsString<T>(T obj) {
90 using(var writer = new StringWriter()) {
87 using (var writer = new StringWriter()) {
91 SerializeJson(writer, obj);
88 SerializeJson(writer, obj);
92 return writer.ToString();
89 return writer.ToString();
93 }
90 }
@@ -9,6 +9,7 using System.Xml;
9 using System.Xml.Serialization;
9 using System.Xml.Serialization;
10
10
11 namespace Implab.Xml {
11 namespace Implab.Xml {
12 [Obsolete("this class will be removed, use XmlDefaultSerializer")]
12 public class SerializersPool<T> : ObjectPool<XmlSerializer> {
13 public class SerializersPool<T> : ObjectPool<XmlSerializer> {
13
14
14 static readonly SerializersPool<T> _instance = new SerializersPool<T>();
15 static readonly SerializersPool<T> _instance = new SerializersPool<T>();
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