##// END OF EJS Templates
Working on Unity container xml configuration
cin -
r269:ff581cff7003 v3
parent child
Show More
@@ -0,0 +1,7
1 namespace Implab.ServiceHost.Unity
2 {
3 public abstract class AbstractInjectorElement
4 {
5
6 }
7 } No newline at end of file
@@ -0,0 +1,22
1 using System;
2 using System.Xml.Serialization;
3 using Unity.Lifetime;
4 using Unity.Registration;
5
6 namespace Implab.ServiceHost.Unity
7 {
8 public abstract class AbstractRegistration : IConfigurationElement {
9
10 /// <summary>
11 /// An optional name for a registration in the container
12 /// </summary>
13 [XmlAttribute("name")]
14 public string Name {
15 get; set;
16 }
17
18 public void Visit(ConfigurationContext context) {
19 context.Visist(this);
20 }
21 }
22 } No newline at end of file
@@ -0,0 +1,14
1 using System.Xml.Serialization;
2
3 namespace Implab.ServiceHost.Unity
4 {
5 [XmlRoot("assembly", Namespace = Schema.ContainerConfigurationNamespace)]
6 public class AssemblyElement : IConfigurationElement {
7 [XmlAttribute("name")]
8 public string AssemblyName { get; set; }
9
10 public void Visit(ConfigurationContext context) {
11 throw new System.NotImplementedException();
12 }
13 }
14 } No newline at end of file
@@ -0,0 +1,47
1 using System;
2 using System.Collections.Generic;
3 using System.Reflection;
4 using System.Xml;
5 using System.Xml.Serialization;
6 using Implab.Components;
7
8 namespace Implab.ServiceHost.Unity {
9 public class ConfigurationSchema {
10
11 public static ConfigurationSchema Default { get; private set; } = CreateDefault();
12
13 readonly Dictionary<Tuple<string,string>, LazyAndWeak<XmlSerializer>> m_mappings = new Dictionary<Tuple<string, string>, LazyAndWeak<XmlSerializer>>();
14
15 public void DefineMapping(string name, string ns, Type type) {
16 Safe.ArgumentNotEmpty(name, nameof(name));
17 Safe.ArgumentNotNull(type, nameof(type));
18 ns = ns ?? string.Empty;
19 m_mappings[Tuple.Create(name, ns)] = new LazyAndWeak<XmlSerializer>(() => new XmlSerializer(type), true);
20 }
21
22 public void DefineMapping<T>() {
23 var xmlRoot = typeof(T).GetCustomAttribute<XmlRootAttribute>();
24 var ns = xmlRoot?.Namespace;
25 var root = xmlRoot?.ElementName ?? typeof(T).Name;
26 DefineMapping(root, ns, typeof(T));
27 }
28
29 public T Deserialize<T>(XmlReader reader) {
30 reader.MoveToContent();
31 var name = reader.Name;
32 var ns = reader.NamespaceURI;
33
34 return (T)m_mappings[Tuple.Create(name, ns)].Value.Deserialize(reader);
35 }
36
37 static ConfigurationSchema CreateDefault() {
38 var schema = new ConfigurationSchema();
39
40 schema.DefineMapping<RegisterElement>();
41
42 return schema;
43 }
44
45
46 }
47 } No newline at end of file
@@ -0,0 +1,5
1 namespace Implab.ServiceHost.Unity {
2 public class ConstructorInjectorElement : AbstractInjectorElement {
3
4 }
5 } No newline at end of file
@@ -0,0 +1,10
1 using Unity.Lifetime;
2
3 namespace Implab.ServiceHost.Unity
4 {
5 public class ContainerLifetimeElement : LifetimeElement {
6 public override LifetimeManager GetLifetimeManager(ConfigurationContext ctx) {
7 return new ContainerControlledLifetimeManager();
8 }
9 }
10 } No newline at end of file
@@ -0,0 +1,10
1 using Unity.Lifetime;
2
3 namespace Implab.ServiceHost.Unity
4 {
5 public class ContextLifetimeElement : LifetimeElement {
6 public override LifetimeManager GetLifetimeManager(ConfigurationContext ctx) {
7 return new PerResolveLifetimeManager();
8 }
9 }
10 } No newline at end of file
@@ -0,0 +1,10
1 using Unity.Lifetime;
2
3 namespace Implab.ServiceHost.Unity
4 {
5 public class HierarchicalLifetimeElement : LifetimeElement {
6 public override LifetimeManager GetLifetimeManager(ConfigurationContext ctx) {
7 return new HierarchicalLifetimeManager();
8 }
9 }
10 } No newline at end of file
@@ -0,0 +1,5
1 namespace Implab.ServiceHost.Unity {
2 public interface IConfigurationElement {
3 void Visit(ConfigurationContext context);
4 }
5 } No newline at end of file
@@ -0,0 +1,13
1 using System.Xml.Serialization;
2
3 namespace Implab.ServiceHost.Unity {
4 [XmlRoot("include", Namespace = Schema.ContainerConfigurationNamespace)]
5 public class IncludeElement : IConfigurationElement {
6 [XmlAttribute("href")]
7 public string Href { get; set; }
8
9 public void Visit(ConfigurationContext context) {
10 context.Include(Href);
11 }
12 }
13 } No newline at end of file
@@ -0,0 +1,10
1 using Unity.Lifetime;
2
3 namespace Implab.ServiceHost.Unity
4 {
5 public abstract class LifetimeElement
6 {
7 public abstract LifetimeManager GetLifetimeManager(ConfigurationContext ctx);
8
9 }
10 } No newline at end of file
@@ -0,0 +1,13
1 using System.Xml.Serialization;
2
3 namespace Implab.ServiceHost.Unity {
4 public class MethodInjectorElement : AbstractInjectorElement {
5
6 [XmlAttribute("name")]
7 public string Name { get; set; }
8
9 [XmlElement("params")]
10 public MethodInjectorParameter[] Parameters { get; set; }
11
12 }
13 } No newline at end of file
@@ -0,0 +1,7
1 namespace Implab.ServiceHost.Unity
2 {
3 public class MethodInjectorParameter
4 {
5
6 }
7 } No newline at end of file
@@ -0,0 +1,15
1 using System.Xml.Serialization;
2
3 namespace Implab.ServiceHost.Unity
4 {
5 [XmlRoot("namespace", Namespace = Schema.ContainerConfigurationNamespace)]
6 public class NamespaceElement : IConfigurationElement {
7
8 [XmlAttribute("name")]
9 public string Name { get; set; }
10
11 public void Visit(ConfigurationContext context) {
12 throw new System.NotImplementedException();
13 }
14 }
15 } No newline at end of file
@@ -0,0 +1,6
1 namespace Implab.ServiceHost.Unity {
2 public class PropertyInjectorElement : AbstractInjectorElement {
3
4
5 }
6 } No newline at end of file
@@ -0,0 +1,36
1 using System;
2 using System.Xml.Serialization;
3 using Unity.Lifetime;
4 using Unity.Registration;
5
6 namespace Implab.ServiceHost.Unity {
7
8 [XmlRoot("register", Namespace = Schema.ContainerConfigurationNamespace)]
9 public class RegisterElement : AbstractRegistration {
10
11 /// <summary>
12 /// An optional type specification for the service registration,
13 /// must be assignable from the type specified by <see cref="ImplementedType"/>
14 /// </summary>
15 [XmlAttribute("provides")]
16 public string ProvidesType { get; set; }
17
18 /// <summary>
19 /// The type which is registered as a service in the container.
20 /// </summary>
21 [XmlAttribute("type")]
22 public string ImplementedType { get; set; }
23
24 [XmlElement("signleton", typeof(SimgletonLifetimeElement))]
25 [XmlElement("context", typeof(ContextLifetimeElement))]
26 [XmlElement("container", typeof(ContainerLifetimeElement))]
27 [XmlElement("hierarchy", typeof(HierarchicalLifetimeElement))]
28 public LifetimeElement Lifetime {get; set;}
29
30 [XmlElement("constructor", typeof(ConstructorInjectorElement))]
31 [XmlElement("property", typeof(PropertyInjectorElement))]
32 [XmlElement("method", typeof(MethodInjectorElement))]
33 public AbstractInjectorElement[] Injectors { get; set; }
34 }
35
36 } No newline at end of file
@@ -0,0 +1,10
1 using Unity.Lifetime;
2
3 namespace Implab.ServiceHost.Unity
4 {
5 public class SimgletonLifetimeElement : LifetimeElement {
6 public override LifetimeManager GetLifetimeManager(ConfigurationContext ctx) {
7 return new SingletonLifetimeManager();
8 }
9 }
10 } No newline at end of file
@@ -9,6 +9,11 using Unity.Injection;
9 namespace Implab.Playground {
9 namespace Implab.Playground {
10
10
11 public class Foo {
11 public class Foo {
12
13 public class Bar {
14
15 }
16
12 public int IntValue { get; set; }
17 public int IntValue { get; set; }
13
18
14 public string StringValue { get; set; }
19 public string StringValue { get; set; }
@@ -32,20 +37,10 namespace Implab.Playground {
32 static void Main(string[] args) {
37 static void Main(string[] args) {
33 var container = new UnityContainer();
38 var container = new UnityContainer();
34
39
35 var listener = new SimpleTraceListener(Console.Out);
40 var conf = SerializationHelpers.DeserializeFromFile<ContainerElement>("data/sample.xml");
36 Trace<ConfigurationContext>.TraceSource.Switch.Level = SourceLevels.All;
37 Trace<ConfigurationContext>.TraceSource.Listeners.Add(listener);
38
39 var c = new Container<int>();
40
41
41 var cts = new ConfigurationContext();
42 Console.WriteLine($"Registrations: {conf.Registrations.Count}");
42 cts.AddNamespace("System");
43 cts.AddNamespace("System.Collections.Generic");
44 cts.AddNamespace("Implab.Playground");
45
43
46 Console.WriteLine(c.GetType().FullName);
47
48 cts.Resolve("Container{Int32}");
49 }
44 }
50
45
51
46
@@ -1,10 +1,10
1 <?xml version="1.0" encoding="UTF-8"?>
1 <?xml version="1.0" encoding="UTF-8"?>
2 <container xmlns="http://implab.org/schemas/servicehost/unity.v1.xsd">
2 <container xmlns="http://implab.org/schemas/servicehost/unity.v1.xsd">
3 <!-- foo1 -->
3 <!-- foo1 -->
4 <register name="foo1" provides="IFoo" type="Foo">
4 <register name="foo1" type="Foo">
5 </register>
5 </register>
6
6
7 <!-- foo2 -->
7 <!-- foo2 -->
8 <register name="foo2" provides="IFoo" type="Foo">
8 <register name="foo2" type="Foo">
9 </register>
9 </register>
10 </container> No newline at end of file
10 </container>
@@ -5,7 +5,9 using Implab.Diagnostics;
5
5
6 namespace Implab.ServiceHost.Unity {
6 namespace Implab.ServiceHost.Unity {
7 using System.Linq;
7 using System.Linq;
8 using System.Reflection;
8 using System.Text;
9 using System.Text;
10 using global::Unity;
9 using static Trace<ConfigurationContext>;
11 using static Trace<ConfigurationContext>;
10
12
11 public class ConfigurationContext {
13 public class ConfigurationContext {
@@ -14,7 +16,10 namespace Implab.ServiceHost.Unity {
14
16
15 LinkedListNode<string> m_insertAt;
17 LinkedListNode<string> m_insertAt;
16
18
17 public ConfigurationContext() {
19 readonly UnityContainer m_container;
20
21 public ConfigurationContext(UnityContainer container) {
22 m_container = container ?? new UnityContainer();
18 m_insertAt = new LinkedListNode<string>(string.Empty);
23 m_insertAt = new LinkedListNode<string>(string.Empty);
19 m_namespases.AddFirst(m_insertAt);
24 m_namespases.AddFirst(m_insertAt);
20 }
25 }
@@ -36,9 +41,9 namespace Implab.ServiceHost.Unity {
36 foreach (var ns in m_namespases) {
41 foreach (var ns in m_namespases) {
37 var typeName = FormatName(new [] { ns, reference.Namespace, reference.TypeName}, argc, args, reference.IsArray);
42 var typeName = FormatName(new [] { ns, reference.Namespace, reference.TypeName}, argc, args, reference.IsArray);
38
43
39 var resolved = Type.GetType(typeName, false);
44 var resolved = ProbeType(typeName);
40 if (resolved != null) {
45 if (resolved != null) {
41 Log("Probe succeed {0} in '{1}': {2} -> {3}", reference, ns, typeName, resolved.FullName);
46 Log("Probe succeed {0} in '{1}': {2} -> {3}", reference, ns, typeName, resolved.AssemblyQualifiedName);
42 return resolved;
47 return resolved;
43 } else {
48 } else {
44 Log("Probe failed {0} in '{1}': {2}", reference, ns, typeName);
49 Log("Probe failed {0} in '{1}': {2}", reference, ns, typeName);
@@ -48,6 +53,17 namespace Implab.ServiceHost.Unity {
48 throw new Exception($"Failed to resolve: {reference}");
53 throw new Exception($"Failed to resolve: {reference}");
49 }
54 }
50
55
56 Type ProbeType(string typeName) {
57 var assemblies = AppDomain.CurrentDomain.GetAssemblies();
58
59 foreach(var assembly in assemblies) {
60 var type = assembly.GetType(typeName);
61 if (type != null)
62 return type;
63 }
64 return null;
65 }
66
51 string FormatName(string[] parts, int argc, Type[] args, bool isArray) {
67 string FormatName(string[] parts, int argc, Type[] args, bool isArray) {
52 var builder = new StringBuilder();
68 var builder = new StringBuilder();
53
69
@@ -59,7 +75,7 namespace Implab.ServiceHost.Unity {
59
75
60 if (args!= null && args.Length > 0) {
76 if (args!= null && args.Length > 0) {
61 builder.Append('[');
77 builder.Append('[');
62 builder.Append(string.Join(",", args.Select(x => x.FullName)));
78 builder.Append(string.Join(",", args.Select(x => $"[{x.AssemblyQualifiedName}]")));
63 builder.Append(']');
79 builder.Append(']');
64 }
80 }
65
81
@@ -73,7 +89,11 namespace Implab.ServiceHost.Unity {
73 return Resolve(TypeReference.Parse(typeReference));
89 return Resolve(TypeReference.Parse(typeReference));
74 }
90 }
75
91
76 public void Register(ServiceElement descriptor) {
92 public void Visist(AbstractRegistration descriptor) {
93
94 }
95
96 public void Include(string file) {
77
97
78 }
98 }
79
99
@@ -8,7 +8,7 namespace Implab.ServiceHost.Unity {
8 [XmlRoot("container", Namespace = Schema.ContainerConfigurationNamespace)]
8 [XmlRoot("container", Namespace = Schema.ContainerConfigurationNamespace)]
9 public class ContainerElement : IXmlSerializable {
9 public class ContainerElement : IXmlSerializable {
10
10
11 public List<ServiceElement> Registrations {get; set; } = new List<ServiceElement>();
11 public List<IConfigurationElement> Registrations {get; set; } = new List<IConfigurationElement>();
12
12
13 public XmlSchema GetSchema() {
13 public XmlSchema GetSchema() {
14 return null;
14 return null;
@@ -16,7 +16,7 namespace Implab.ServiceHost.Unity {
16
16
17 public void ReadXml(XmlReader reader) {
17 public void ReadXml(XmlReader reader) {
18 while(reader.Read() && reader.NodeType != XmlNodeType.EndElement) {
18 while(reader.Read() && reader.NodeType != XmlNodeType.EndElement) {
19 var registration = SerializationHelpers.Deserialize<ServiceElement>(reader);
19 var registration = ConfigurationSchema.Default.Deserialize<IConfigurationElement>(reader);
20 Registrations.Add(registration);
20 Registrations.Add(registration);
21 }
21 }
22 }
22 }
@@ -20,7 +20,7 namespace Implab.ServiceHost.Unity {
20 Eof
20 Eof
21 }
21 }
22
22
23 readonly Regex _tokens = new Regex(@"(\w+)|\s*([\.{},\+])\s*");
23 readonly Regex _tokens = new Regex(@"([\w\+]+)|\s*([\.{},])\s*");
24
24
25 TokenType m_token;
25 TokenType m_token;
26
26
@@ -68,7 +68,6 namespace Implab.ServiceHost.Unity {
68 m_token = TokenType.CloseList;
68 m_token = TokenType.CloseList;
69 break;
69 break;
70 case ".":
70 case ".":
71 case "+":
72 m_token = TokenType.Dot;
71 m_token = TokenType.Dot;
73 break;
72 break;
74 case ",":
73 case ",":
1 NO CONTENT: file was removed
NO CONTENT: file was removed
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