##// END OF EJS Templates
Unity xml configuration, alpha2
cin -
r274:22629bf26121 v3
parent child
Show More
@@ -0,0 +1,125
1 using System;
2 using System.Collections.Generic;
3 using System.Text.RegularExpressions;
4 using Implab.Diagnostics;
5
6 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 {
16
17 readonly TypeResolver m_resolver;
18
19 readonly UnityContainer m_container;
20
21 readonly ContainerConfigurationSchema m_schema;
22
23 public UnityContainer Container {
24 get {
25 return m_container;
26 }
27 }
28
29 public ContainerBuilder() : this(null, null) {
30 }
31
32 public ContainerBuilder(UnityContainer container, ContainerConfigurationSchema schema) {
33 m_container = container ?? new UnityContainer();
34 m_resolver = new TypeResolver();
35 m_schema = schema ?? ContainerConfigurationSchema.Default;
36 }
37
38 public Type ResolveType(string typeReference) {
39 return m_resolver.Resolve(typeReference);
40 }
41
42 internal void Visit(RegisterElement registerElement) {
43 var registrationType = ResolveType(registerElement.RegistrationType);
44 var implementationType = string.IsNullOrEmpty(registerElement.MapToType) ? registrationType : ResolveType(registerElement.MapToType);
45
46 var registrationContext = new TypeRegistrationBuilder(
47 m_resolver,
48 registrationType,
49 implementationType
50 );
51
52 if (registerElement.Injectors != null) {
53 foreach (var injector in registerElement.Injectors) {
54 injector.Visit(registrationContext);
55 }
56 }
57
58 m_container.RegisterType(
59 registrationContext.RegistrationType,
60 registrationContext.ImplementationType,
61 registerElement.Name,
62 registerElement.Lifetime?.GetLifetimeManager(this),
63 registrationContext.Injections
64 );
65 }
66
67 internal void Visit(SerializedElement serializedElement) {
68 var registrationType = ResolveType(serializedElement.RegistrationType);
69 var valueBuilder = new InjectionValueBuilder(m_resolver, null);
70
71 valueBuilder.Visit(serializedElement);
72
73 m_container.RegisterInstance(
74 registrationType,
75 serializedElement.Name,
76 valueBuilder.Value,
77 serializedElement.Lifetime?.GetLifetimeManager(this)
78 );
79 }
80
81 internal void Visit(ValueElement valueElement) {
82 var registrationType = ResolveType(valueElement.RegistrationType);
83 var valueBuilder = new InjectionValueBuilder(m_resolver, null);
84
85 valueBuilder.Visit(valueElement);
86
87 m_container.RegisterInstance(
88 registrationType,
89 valueElement.Name,
90 valueBuilder.Value,
91 valueElement.Lifetime?.GetLifetimeManager(this)
92 );
93 }
94
95 internal void Visit(NamespaceElement namespaceElement) {
96 m_resolver.AddNamespace(namespaceElement.Name);
97 }
98
99 internal void Visit(AssemblyElement assemblyElement) {
100 Assembly.Load(assemblyElement.AssemblyName);
101 }
102
103 internal void Visit(IncludeElement includeElement) {
104 Include(includeElement.Href);
105 }
106
107 public void Include(string file) {
108 var includeContext = new ContainerBuilder(m_container, m_schema);
109 includeContext.LoadConfig(file);
110 }
111
112 public void LoadConfig(string file) {
113 var config = m_schema.LoadFile(file);
114 Visit(config);
115 }
116
117 internal void Visit(ContainerElement containerElement) {
118 foreach (var item in containerElement.Items)
119 item.Visit(this);
120 }
121
122
123
124 }
125 } No newline at end of file
@@ -0,0 +1,7
1 namespace Implab.ServiceHost.Unity {
2 public class FactoryInjectionElement : AbstractInjectionElement {
3 internal override void Visit(TypeRegistrationBuilder context) {
4
5 }
6 }
7 } No newline at end of file
@@ -0,0 +1,64
1 using System;
2 using System.ComponentModel;
3 using System.Xml.Serialization;
4 using Unity.Injection;
5
6 namespace Implab.ServiceHost.Unity {
7
8 public class InjectionValueBuilder {
9
10 readonly TypeResolver m_resolver;
11
12 public Type DefaultType { get; private set; }
13
14 public Type ValueType { get; set; }
15
16 public object Value { get; set; }
17
18 public InjectionParameterValue Injection {
19 get {
20 if (Value != null)
21 return InjectionParameterValue.ToParameter(Value);
22
23 return new InjectionParameter(ValueType, null);
24 }
25 }
26
27 internal InjectionValueBuilder(TypeResolver resolver, Type acceptsType) {
28 m_resolver = resolver;
29 DefaultType = acceptsType;
30 }
31
32 public Type ResolveType(string typeSpec) {
33 if (string.IsNullOrEmpty(typeSpec)) {
34 if (DefaultType == null)
35 throw new Exception("The type must be specified");
36 return DefaultType;
37 }
38 return m_resolver.Resolve(typeSpec);
39 }
40
41 public void Visit(ITextValue value) {
42 ValueType = ResolveType(value.TypeName);
43
44 Value = string.IsNullOrEmpty(value.Value) ?
45 Safe.CreateDefaultValue(ValueType) :
46 TypeDescriptor.GetConverter(ValueType).ConvertFromString(value.Value);
47 }
48
49 public void Visit(ISerializedValue value) {
50 ValueType = ResolveType(value.TypeName);
51
52 var serializer = new XmlSerializer(ValueType);
53
54 using (var reader = value.GetReader())
55 Value = new InjectionParameter(ValueType, serializer.Deserialize(reader));
56 }
57
58 public void Visit(IDependencyReference value) {
59 ValueType = ResolveType(value.TypeName);
60 Value = new ResolvedParameter(ValueType, value.DependencyName);
61 }
62
63 }
64 } No newline at end of file
@@ -0,0 +1,21
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 public abstract class RegistrationBuilder {
12 public Type RegistrationType {
13 get;
14 private set;
15 }
16
17 protected RegistrationBuilder(Type registrationType) {
18 RegistrationType = registrationType;
19 }
20 }
21 } No newline at end of file
@@ -0,0 +1,77
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using Unity.Injection;
5 using Unity.Registration;
6
7 namespace Implab.ServiceHost.Unity {
8 public class TypeRegistrationBuilder : RegistrationBuilder {
9
10 readonly TypeResolver m_resolver;
11
12 readonly List<InjectionMember> m_injections = new List<InjectionMember>();
13
14 public InjectionMember[] Injections { get { return m_injections.ToArray(); } }
15
16 public Type ImplementationType {
17 get;
18 private set;
19 }
20
21 internal TypeRegistrationBuilder(TypeResolver resolver, Type registrationType, Type implementationType) : base(registrationType) {
22 ImplementationType = implementationType;
23
24 // when registering a generic mapping, register all generic parameter names as local types
25 if (ImplementationType.IsGenericTypeDefinition) {
26 m_resolver = new TypeResolver(resolver);
27
28 foreach (var p in ImplementationType.GetGenericArguments())
29 m_resolver.AddMapping(p.Name, p);
30 } else {
31 m_resolver = resolver;
32 }
33 }
34
35 internal void Visit(ConstructorInjectionElement constructorInjection) {
36
37
38 var parameters = constructorInjection.Parameters?
39 .Select(x => {
40 var valueBuilder = new InjectionValueBuilder(m_resolver, null);
41 x.Visit(valueBuilder);
42 return valueBuilder.Injection;
43 })
44 .ToArray();
45
46 var injection = parameters != null ? new InjectionConstructor(parameters) : new InjectionConstructor();
47 m_injections.Add(injection);
48 }
49
50 internal void Visit(MethodInjectionElement methodInjection) {
51 var valueContext = new InjectionValueBuilder(m_resolver, null);
52
53 var parameters = methodInjection.Parameters?
54 .Select(x => {
55 var valueBuilder = new InjectionValueBuilder(m_resolver, null);
56 x.Visit(valueBuilder);
57 return valueBuilder.Injection;
58 })
59 .ToArray();
60
61 var injection = parameters != null ? new InjectionMethod(methodInjection.Name, parameters) : new InjectionMethod(methodInjection.Name);
62 m_injections.Add(injection);
63 }
64
65 internal void Visit(PropertyInjectionElement propertyInjection) {
66 if (propertyInjection.Value == null)
67 throw new Exception($"A value value must be specified for the property '{propertyInjection.Name}'");
68
69 var propertyType = RegistrationType.GetProperty(propertyInjection.Name)?.PropertyType;
70 var valueContext = new InjectionValueBuilder(m_resolver, propertyType);
71
72 propertyInjection.Value.Visit(valueContext);
73 var injection = new InjectionProperty(propertyInjection.Name, valueContext.Injection);
74 m_injections.Add(injection);
75 }
76 }
77 } No newline at end of file
@@ -1,95 +1,95
1 using System;
1 using System;
2 using System.Diagnostics;
2 using System.Diagnostics;
3 using System.Linq;
3 using System.Linq;
4 using Implab.Diagnostics;
4 using Implab.Diagnostics;
5 using Implab.ServiceHost.Unity;
5 using Implab.ServiceHost.Unity;
6 using Implab.Xml;
6 using Implab.Xml;
7 using Unity;
7 using Unity;
8 using Unity.Injection;
8 using Unity.Injection;
9 using Unity.Registration;
9 using Unity.Registration;
10
10
11 namespace Implab.Playground {
11 namespace Implab.Playground {
12
12
13 public class Foo {
13 public class Foo {
14
14
15 public class Bar {
15 public class Bar {
16
16
17 }
17 }
18
18
19 public string Name { get; set; }
19 public string Name { get; set; }
20
20
21 public int IntValue { get; set; }
21 public int IntValue { get; set; }
22
22
23 public string StringValue { get; set; }
23 public string StringValue { get; set; }
24
24
25 }
25 }
26
26
27 public interface IContainer<T> {
27 public interface IContainer<T> {
28 T Instance { get; set; }
28 T Instance { get; set; }
29 }
29 }
30
30
31 public class Container<T> : IContainer<T> {
31 public class Container<T> : IContainer<T> {
32 public Container() {
32 public Container() {
33
33
34 }
34 }
35
35
36 public Container(T instance) {
36 public Container(T instance) {
37 Instance = instance;
37 Instance = instance;
38 }
38 }
39
39
40 public T Instance { get; set; }
40 public T Instance { get; set; }
41
41
42 public void SetInstance(T value) {
42 public void SetInstance(T value) {
43 Instance = value;
43 Instance = value;
44 }
44 }
45 }
45 }
46
46
47 public class Program {
47 public class Program {
48
48
49 static void Main(string[] args) {
49 static void Main(string[] args) {
50 var stopwatch = new Stopwatch();
50 var stopwatch = new Stopwatch();
51 stopwatch.Start();
51 stopwatch.Start();
52
52
53 var ctx = new ContainerContext();
53 var ctx = new ContainerBuilder();
54
54
55 Console.WriteLine($"Created: {stopwatch.ElapsedMilliseconds}");
55 Console.WriteLine($"Created: {stopwatch.ElapsedMilliseconds}");
56
56
57 ctx.LoadConfig("data/sample.xml");
57 ctx.LoadConfig("data/sample.xml");
58
58
59 Console.WriteLine($"Loaded: {stopwatch.ElapsedMilliseconds}");
59 Console.WriteLine($"Loaded: {stopwatch.ElapsedMilliseconds}");
60
60
61 var container = ctx.Container;
61 var container = ctx.Container;
62
62
63
63
64
64
65 var instace1 = container.Resolve<IContainer<string>>();
65 var instace1 = container.Resolve<IContainer<string>>();
66 Console.WriteLine($"Resolved1: {stopwatch.ElapsedMilliseconds}");
66 Console.WriteLine($"Resolved1: {stopwatch.ElapsedMilliseconds}");
67 var instace2 = container.Resolve<IContainer<Foo>>();
67 var instace2 = container.Resolve<IContainer<Foo>>();
68
68
69 Console.WriteLine($"Resolved2: {stopwatch.ElapsedMilliseconds}");
69 Console.WriteLine($"Resolved2: {stopwatch.ElapsedMilliseconds}");
70
70
71 DisplayContainerRegistrations(container);
71 DisplayContainerRegistrations(container);
72 }
72 }
73
73
74 static void DisplayContainerRegistrations(IUnityContainer theContainer) {
74 static void DisplayContainerRegistrations(IUnityContainer theContainer) {
75 string regName, regType, mapTo, lifetime;
75 string regName, regType, mapTo, lifetime;
76 Console.WriteLine("Container has {0} Registrations:",
76 Console.WriteLine("Container has {0} Registrations:",
77 theContainer.Registrations.Count());
77 theContainer.Registrations.Count());
78 foreach (ContainerRegistration item in theContainer.Registrations) {
78 foreach (ContainerRegistration item in theContainer.Registrations) {
79 regType = item.RegisteredType.FullName;
79 regType = item.RegisteredType.FullName;
80 mapTo = item.MappedToType.FullName;
80 mapTo = item.MappedToType.FullName;
81 regName = item.Name ?? "[default]";
81 regName = item.Name ?? "[default]";
82 lifetime = item.LifetimeManager.LifetimeType.Name;
82 lifetime = item.LifetimeManager.LifetimeType.Name;
83 if (mapTo != regType) {
83 if (mapTo != regType) {
84 mapTo = " -> " + mapTo;
84 mapTo = " -> " + mapTo;
85 } else {
85 } else {
86 mapTo = string.Empty;
86 mapTo = string.Empty;
87 }
87 }
88 lifetime = lifetime.Substring(0, lifetime.Length - "LifetimeManager".Length);
88 lifetime = lifetime.Substring(0, lifetime.Length - "LifetimeManager".Length);
89 Console.WriteLine("+ {0}{1} '{2}' {3}", regType, mapTo, regName, lifetime);
89 Console.WriteLine("+ {0}{1} '{2}' {3}", regType, mapTo, regName, lifetime);
90 }
90 }
91 }
91 }
92
92
93
93
94 }
94 }
95 }
95 }
@@ -1,49 +1,49
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 <namespace name="System"/>
3 <namespace name="System"/>
4 <namespace name="Implab.Playground"/>
4 <namespace name="Implab.Playground"/>
5
5
6 <!-- foo1 -->
6 <!-- foo1 -->
7 <register name="foo1" type="Foo">
7 <register name="foo1" type="Foo">
8 <property name="Name">
8 <property name="Name">
9 <value>FOO!</value>
9 <value>FOO!</value>
10 </property>
10 </property>
11 </register>
11 </register>
12
12
13 <!-- foo2 -->
13 <!-- foo2 -->
14 <register name="foo2" type="Foo">
14 <register name="foo2" type="Foo">
15 <property name="Name">
15 <property name="Name">
16 <value>GOOD</value>
16 <value>GOOD</value>
17 </property>
17 </property>
18 <property name="IntValue">
18 <property name="IntValue">
19 <value>2</value>
19 <value>2</value>
20 </property>
20 </property>
21 </register>
21 </register>
22
22
23 <register type="Foo">
23 <register type="Foo">
24 </register>
24 </register>
25
25
26 <register type="IContainer{}" mapTo="Container{}">
26 <register type="IContainer{}" mapTo="Container{}">
27 <constructor/>
27 <constructor/>
28 <method name="SetInstance">
28 <method name="SetInstance">
29 <dependency type="T"/>
29 <dependency type="T"/>
30 </method>
30 </method>
31 </register>
31 </register>
32
32
33 <register type="IContainer{String}" mapTo="Container{String}">
33 <register type="IContainer{String}" mapTo="Container{String}">
34 <constructor/>
34 <constructor/>
35 <method name="SetInstance">
35 <method name="SetInstance">
36 <dependency type="String" name="name1"/>
36 <dependency type="String" name="name1"/>
37 </method>
37 </method>
38 </register>
38 </register>
39
39
40 <serialized type="Foo+Bar">
40 <serialized type="Foo+Bar">
41 <Bar id="1">
41 <Bar xmlns="" id="1">
42 <Name>Baaar</Name>
42 <Name>Baaar</Name>
43 </Bar>
43 </Bar>
44 </serialized>
44 </serialized>
45
45
46 <value name="connection1" type="String"><![CDATA[Connect me <here>!]]></value>
46 <value name="connection1" type="String"><![CDATA[Connect me <here>!]]></value>
47 <value name="name1" type="String" value="Hello!"/>
47 <value name="name1" type="String" value="Hello!"/>
48
48
49 </container> No newline at end of file
49 </container>
@@ -1,8 +1,10
1 using System;
1 using System;
2
2
3 namespace Implab.ServiceHost.Unity
3 namespace Implab.ServiceHost.Unity {
4 {
4 /// <summary>
5 /// Base class for injections, each injection is applied to the type registration context.
6 /// </summary>
5 public abstract class AbstractInjectionElement {
7 public abstract class AbstractInjectionElement {
6 internal abstract void Visit(TypeRegistrationContext context);
8 internal abstract void Visit(TypeRegistrationBuilder context);
7 }
9 }
8 } No newline at end of file
10 }
@@ -1,35 +1,31
1 using System;
1 using System;
2 using System.Xml.Serialization;
2 using System.Xml.Serialization;
3 using Unity.Lifetime;
3 using Unity.Lifetime;
4 using Unity.Registration;
4 using Unity.Registration;
5
5
6 namespace Implab.ServiceHost.Unity
6 namespace Implab.ServiceHost.Unity
7 {
7 {
8 public abstract class AbstractRegistration : ContainerItemElement {
8 public abstract class AbstractRegistration : ContainerItemElement {
9
9
10 /// <summary>
10 /// <summary>
11 /// An optional name for a registration in the container
11 /// An optional name for a registration in the container
12 /// </summary>
12 /// </summary>
13 [XmlAttribute("name")]
13 [XmlAttribute("name")]
14 public string Name {
14 public string Name {
15 get; set;
15 get; set;
16 }
16 }
17
17
18 [XmlElement("signleton", typeof(SimgletonLifetimeElement))]
18 [XmlElement("signleton", typeof(SimgletonLifetimeElement))]
19 [XmlElement("context", typeof(ContextLifetimeElement))]
19 [XmlElement("context", typeof(ContextLifetimeElement))]
20 [XmlElement("container", typeof(ContainerLifetimeElement))]
20 [XmlElement("container", typeof(ContainerLifetimeElement))]
21 [XmlElement("hierarchy", typeof(HierarchicalLifetimeElement))]
21 [XmlElement("hierarchy", typeof(HierarchicalLifetimeElement))]
22 public LifetimeElement Lifetime {get; set;}
22 public LifetimeElement Lifetime {get; set;}
23
23
24 /// <summary>
24 /// <summary>
25 /// A type specification for the service registration,
25 /// A type specification for the service registration,
26 /// </summary>
26 /// </summary>
27 [XmlAttribute("type")]
27 [XmlAttribute("type")]
28 public string RegistrationType { get; set; }
28 public string RegistrationType { get; set; }
29
29
30 public virtual Type ResolveRegistrationType(ContainerContext ctx) {
31 return ctx.Resolve(RegistrationType);
32 }
33
34 }
30 }
35 } No newline at end of file
31 }
@@ -1,14 +1,14
1 using System.Xml.Serialization;
1 using System.Xml.Serialization;
2
2
3 namespace Implab.ServiceHost.Unity
3 namespace Implab.ServiceHost.Unity
4 {
4 {
5 [XmlRoot("assembly", Namespace = Schema.ContainerConfigurationNamespace)]
5 [XmlRoot("assembly", Namespace = Schema.ContainerConfigurationNamespace)]
6 public class AssemblyElement : ContainerItemElement {
6 public class AssemblyElement : ContainerItemElement {
7 [XmlAttribute("name")]
7 [XmlAttribute("name")]
8 public string AssemblyName { get; set; }
8 public string AssemblyName { get; set; }
9
9
10 public override void Visit(ContainerContext context) {
10 public override void Visit(ContainerBuilder context) {
11 context.Visit(this);
11 context.Visit(this);
12 }
12 }
13 }
13 }
14 } No newline at end of file
14 }
@@ -1,16 +1,16
1 using System.Xml.Serialization;
1 using System.Xml.Serialization;
2
2
3 namespace Implab.ServiceHost.Unity {
3 namespace Implab.ServiceHost.Unity {
4 public class ConstructorInjectionElement : AbstractInjectionElement {
4 public class ConstructorInjectionElement : AbstractInjectionElement {
5
5
6 [XmlElement("dependency", typeof(DependencyParameterElement))]
6 [XmlElement("dependency", typeof(DependencyParameterElement))]
7 [XmlElement("value", typeof(ValueParameterElement))]
7 [XmlElement("value", typeof(ValueParameterElement))]
8 [XmlElement("serialized", typeof(SerializedParameterElement))]
8 [XmlElement("serialized", typeof(SerializedParameterElement))]
9 [XmlElement("default", typeof(DefaultParameterElement))]
9 [XmlElement("default", typeof(DefaultParameterElement))]
10 public InjectionParameterElement[] Parameters { get; set; }
10 public InjectionParameterElement[] Parameters { get; set; }
11
11
12 internal override void Visit(TypeRegistrationContext context) {
12 internal override void Visit(TypeRegistrationBuilder context) {
13 context.Visit(this);
13 context.Visit(this);
14 }
14 }
15 }
15 }
16 } No newline at end of file
16 }
@@ -1,67 +1,69
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.IO;
3 using System.IO;
4 using System.Reflection;
4 using System.Reflection;
5 using System.Xml;
5 using System.Xml;
6 using System.Xml.Serialization;
6 using System.Xml.Serialization;
7 using Implab.Components;
7 using Implab.Components;
8
8
9 namespace Implab.ServiceHost.Unity {
9 namespace Implab.ServiceHost.Unity {
10 public class ContainerConfigurationSchema {
10 public class ContainerConfigurationSchema {
11
11
12 public static ContainerConfigurationSchema Default { get; private set; } = CreateDefault();
12 public static ContainerConfigurationSchema Default { get; private set; } = CreateDefault();
13
13
14 readonly LazyAndWeak<XmlSerializer> m_seralizer;
14 readonly LazyAndWeak<XmlSerializer> m_seralizer;
15
15
16 readonly XmlAttributeOverrides m_overrides = new XmlAttributeOverrides();
16 readonly XmlAttributeOverrides m_overrides = new XmlAttributeOverrides();
17
17
18 readonly XmlAttributes m_containerItems = new XmlAttributes();
18 readonly XmlAttributes m_containerItems = new XmlAttributes();
19
19
20 public XmlSerializer Serializer {
20 public XmlSerializer Serializer {
21 get {
21 get {
22 return m_seralizer.Value;
22 return m_seralizer.Value;
23 }
23 }
24 }
24 }
25
25
26 public ContainerConfigurationSchema() {
26 public ContainerConfigurationSchema() {
27 m_overrides.Add(typeof(ContainerElement), nameof(ContainerElement.Items), m_containerItems);
27 m_overrides.Add(typeof(ContainerElement), nameof(ContainerElement.Items), m_containerItems);
28
28
29 m_seralizer = new LazyAndWeak<XmlSerializer>(() => new XmlSerializer(typeof(ContainerElement), m_overrides));
29 m_seralizer = new LazyAndWeak<XmlSerializer>(() => new XmlSerializer(typeof(ContainerElement), m_overrides));
30 }
30 }
31
31
32 public void RegisterContainerElement(Type type, string name) {
32 public void RegisterContainerElement(Type type, string name) {
33 Safe.ArgumentNotNull(type, nameof(type));
33 Safe.ArgumentNotNull(type, nameof(type));
34 Safe.ArgumentNotEmpty(name, nameof(name));
34 Safe.ArgumentNotEmpty(name, nameof(name));
35
35
36 if(!type.IsSubclassOf(typeof(ContainerItemElement)))
36 if(!type.IsSubclassOf(typeof(ContainerItemElement)))
37 throw new Exception($"RegisterContainerElement '{name}': {type} must be subclass of {typeof(ContainerItemElement)}");
37 throw new Exception($"RegisterContainerElement '{name}': {type} must be subclass of {typeof(ContainerItemElement)}");
38
38
39 m_containerItems.XmlElements.Add(
39 m_containerItems.XmlElements.Add(
40 new XmlElementAttribute(name, type)
40 new XmlElementAttribute(name, type)
41 );
41 );
42 }
42 }
43
43
44 public void RegisterContainerElement<T>(string name) where T : ContainerItemElement {
44 public void RegisterContainerElement<T>(string name) where T : ContainerItemElement {
45 RegisterContainerElement(typeof(T), name);
45 RegisterContainerElement(typeof(T), name);
46 }
46 }
47
47
48 public ContainerElement LoadFile(string file) {
48 public ContainerElement LoadFile(string file) {
49 using (var reader = XmlReader.Create(file)) {
49 using (var reader = XmlReader.Create(file)) {
50 return (ContainerElement)Serializer.Deserialize(reader);
50 return (ContainerElement)Serializer.Deserialize(reader);
51 }
51 }
52 }
52 }
53
53
54 static ContainerConfigurationSchema CreateDefault() {
54 static ContainerConfigurationSchema CreateDefault() {
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<SerializedElement>("serialized");
59 schema.RegisterContainerElement<ValueElement>("value");
58 schema.RegisterContainerElement<IncludeElement>("include");
60 schema.RegisterContainerElement<IncludeElement>("include");
59 schema.RegisterContainerElement<AssemblyElement>("assembly");
61 schema.RegisterContainerElement<AssemblyElement>("assembly");
60 schema.RegisterContainerElement<NamespaceElement>("namespace");
62 schema.RegisterContainerElement<NamespaceElement>("namespace");
61
63
62 return schema;
64 return schema;
63 }
65 }
64
66
65
67
66 }
68 }
67 } No newline at end of file
69 }
@@ -1,17 +1,17
1 using Implab.Xml;
1 using Implab.Xml;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.Xml;
3 using System.Xml;
4 using System.Xml.Schema;
4 using System.Xml.Schema;
5 using System.Xml.Serialization;
5 using System.Xml.Serialization;
6
6
7 namespace Implab.ServiceHost.Unity {
7 namespace Implab.ServiceHost.Unity {
8 [XmlRoot("container", Namespace = Schema.ContainerConfigurationNamespace)]
8 [XmlRoot("container", Namespace = Schema.ContainerConfigurationNamespace)]
9 public class ContainerElement : ContainerItemElement {
9 public class ContainerElement : ContainerItemElement {
10
10
11 public List<ContainerItemElement> Items {get; set; } = new List<ContainerItemElement>();
11 public List<ContainerItemElement> Items { get; set; } = new List<ContainerItemElement>();
12
12
13 public override void Visit(ContainerContext context) {
13 public override void Visit(ContainerBuilder context) {
14 context.Visit(this);
14 context.Visit(this);
15 }
15 }
16 }
16 }
17 } No newline at end of file
17 }
@@ -1,5 +1,5
1 namespace Implab.ServiceHost.Unity {
1 namespace Implab.ServiceHost.Unity {
2 public abstract class ContainerItemElement {
2 public abstract class ContainerItemElement {
3 public abstract void Visit(ContainerContext context);
3 public abstract void Visit(ContainerBuilder context);
4 }
4 }
5 } No newline at end of file
5 }
@@ -1,10 +1,10
1 using Unity.Lifetime;
1 using Unity.Lifetime;
2
2
3 namespace Implab.ServiceHost.Unity
3 namespace Implab.ServiceHost.Unity
4 {
4 {
5 public class ContainerLifetimeElement : LifetimeElement {
5 public class ContainerLifetimeElement : LifetimeElement {
6 public override LifetimeManager GetLifetimeManager(ContainerContext ctx) {
6 public override LifetimeManager GetLifetimeManager(ContainerBuilder ctx) {
7 return new ContainerControlledLifetimeManager();
7 return new ContainerControlledLifetimeManager();
8 }
8 }
9 }
9 }
10 } No newline at end of file
10 }
@@ -1,10 +1,10
1 using Unity.Lifetime;
1 using Unity.Lifetime;
2
2
3 namespace Implab.ServiceHost.Unity
3 namespace Implab.ServiceHost.Unity
4 {
4 {
5 public class ContextLifetimeElement : LifetimeElement {
5 public class ContextLifetimeElement : LifetimeElement {
6 public override LifetimeManager GetLifetimeManager(ContainerContext ctx) {
6 public override LifetimeManager GetLifetimeManager(ContainerBuilder ctx) {
7 return new PerResolveLifetimeManager();
7 return new PerResolveLifetimeManager();
8 }
8 }
9 }
9 }
10 } No newline at end of file
10 }
@@ -1,9 +1,12
1 namespace Implab.ServiceHost.Unity
1 namespace Implab.ServiceHost.Unity
2 {
2 {
3 public class DefaultParameterElement : InjectionParameterElement {
3 public class DefaultParameterElement : InjectionParameterElement, ITextValue {
4 internal override object Resolve(InjectionValueContext context) {
4 public string Value {
5 var type = context.ResolveType(TypeName);
5 get { return null; }
6 return Safe.CreateDefaultValue(type);
6 }
7
8 internal override void Visit(InjectionValueBuilder builder) {
9 builder.Visit(this);
7 }
10 }
8 }
11 }
9 } No newline at end of file
12 }
@@ -1,12 +1,16
1 using System.Xml.Serialization;
1 using System.Xml.Serialization;
2
2
3 namespace Implab.ServiceHost.Unity {
3 namespace Implab.ServiceHost.Unity {
4 public class DependencyParameterElement : InjectionParameterElement {
4 public class DependencyParameterElement : InjectionParameterElement, IDependencyReference {
5
5
6 [XmlAttribute("name")]
6 [XmlAttribute("name")]
7 public string DependencyName { get; set; }
7 public string DependencyName { get; set; }
8
8
9 [XmlAttribute("optional")]
9 [XmlAttribute("optional")]
10 public bool Optional { get; set; }
10 public bool Optional { get; set; }
11
12 internal override void Visit(InjectionValueBuilder builder) {
13 builder.Visit(this);
14 }
11 }
15 }
12 } No newline at end of file
16 }
@@ -1,10 +1,10
1 using Unity.Lifetime;
1 using Unity.Lifetime;
2
2
3 namespace Implab.ServiceHost.Unity
3 namespace Implab.ServiceHost.Unity
4 {
4 {
5 public class HierarchicalLifetimeElement : LifetimeElement {
5 public class HierarchicalLifetimeElement : LifetimeElement {
6 public override LifetimeManager GetLifetimeManager(ContainerContext ctx) {
6 public override LifetimeManager GetLifetimeManager(ContainerBuilder ctx) {
7 return new HierarchicalLifetimeManager();
7 return new HierarchicalLifetimeManager();
8 }
8 }
9 }
9 }
10 } No newline at end of file
10 }
@@ -1,5 +1,8
1 namespace Implab.ServiceHost.Unity {
1 namespace Implab.ServiceHost.Unity {
2 public interface IDependencyReference {
2 public interface IDependencyReference {
3 string Name { get; set; }
3
4 string TypeName { get; set; }
5
6 string DependencyName { get; set; }
4 }
7 }
5 } No newline at end of file
8 }
@@ -1,7 +1,11
1 namespace Implab.ServiceHost.Unity
1 using System.Xml;
2 {
2
3 public class ISerializedValue
3 namespace Implab.ServiceHost.Unity {
4 {
4 public interface ISerializedValue {
5
5
6 string TypeName { get; }
7
8 XmlReader GetReader();
9
6 }
10 }
7 } No newline at end of file
11 }
@@ -1,6 +1,8
1 namespace Implab.ServiceHost.Unity {
1 namespace Implab.ServiceHost.Unity {
2 public interface ITextValue {
2 public interface ITextValue {
3 string TypeName { get; }
4
3 string Value { get; }
5 string Value { get; }
4
6
5 }
7 }
6 } No newline at end of file
8 }
@@ -1,13 +1,13
1 using System.Xml.Serialization;
1 using System.Xml.Serialization;
2
2
3 namespace Implab.ServiceHost.Unity {
3 namespace Implab.ServiceHost.Unity {
4 [XmlRoot("include", Namespace = Schema.ContainerConfigurationNamespace)]
4 [XmlRoot("include", Namespace = Schema.ContainerConfigurationNamespace)]
5 public class IncludeElement : ContainerItemElement {
5 public class IncludeElement : ContainerItemElement {
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(ContainerContext context) {
9 public override void Visit(ContainerBuilder context) {
10 context.Visit(this);
10 context.Visit(this);
11 }
11 }
12 }
12 }
13 } No newline at end of file
13 }
@@ -1,16 +1,12
1 using System;
1 using System;
2 using System.Xml.Serialization;
2 using System.Xml.Serialization;
3
3
4 namespace Implab.ServiceHost.Unity {
4 namespace Implab.ServiceHost.Unity {
5 public abstract class InjectionParameterElement {
5 public abstract class InjectionParameterElement {
6
6
7 [XmlAttribute("type")]
7 [XmlAttribute("type")]
8 public string TypeName { get; set; }
8 public string TypeName { get; set; }
9
9
10 internal abstract object Resolve(InjectionValueContext context);
10 internal abstract void Visit(InjectionValueBuilder builder);
11
12 public virtual Type ResolveParameterType(InjectionValueContext context) {
13 return context.ResolveType(TypeName);
14 }
15 }
11 }
16 } No newline at end of file
12 }
@@ -1,10 +1,10
1 using Unity.Lifetime;
1 using Unity.Lifetime;
2
2
3 namespace Implab.ServiceHost.Unity
3 namespace Implab.ServiceHost.Unity
4 {
4 {
5 public abstract class LifetimeElement
5 public abstract class LifetimeElement
6 {
6 {
7 public abstract LifetimeManager GetLifetimeManager(ContainerContext ctx);
7 public abstract LifetimeManager GetLifetimeManager(ContainerBuilder ctx);
8
8
9 }
9 }
10 } No newline at end of file
10 }
@@ -1,19 +1,19
1 using System.Xml.Serialization;
1 using System.Xml.Serialization;
2
2
3 namespace Implab.ServiceHost.Unity {
3 namespace Implab.ServiceHost.Unity {
4 public class MethodInjectionElement : AbstractInjectionElement {
4 public class MethodInjectionElement : AbstractInjectionElement {
5
5
6 [XmlAttribute("name")]
6 [XmlAttribute("name")]
7 public string Name { get; set; }
7 public string Name { get; set; }
8
8
9 [XmlElement("dependency", typeof(DependencyParameterElement))]
9 [XmlElement("dependency", typeof(DependencyParameterElement))]
10 [XmlElement("value", typeof(ValueParameterElement))]
10 [XmlElement("value", typeof(ValueParameterElement))]
11 [XmlElement("serialized", typeof(SerializedParameterElement))]
11 [XmlElement("serialized", typeof(SerializedParameterElement))]
12 [XmlElement("default", typeof(DefaultParameterElement))]
12 [XmlElement("default", typeof(DefaultParameterElement))]
13 public InjectionParameterElement[] Parameters { get; set; }
13 public InjectionParameterElement[] Parameters { get; set; }
14
14
15 internal override void Visit(RegistrationContext context) {
15 internal override void Visit(TypeRegistrationBuilder context) {
16 context.Visit(this);
16 context.Visit(this);
17 }
17 }
18 }
18 }
19 } No newline at end of file
19 }
@@ -1,15 +1,15
1 using System.Xml.Serialization;
1 using System.Xml.Serialization;
2
2
3 namespace Implab.ServiceHost.Unity
3 namespace Implab.ServiceHost.Unity
4 {
4 {
5 [XmlRoot("namespace", Namespace = Schema.ContainerConfigurationNamespace)]
5 [XmlRoot("namespace", Namespace = Schema.ContainerConfigurationNamespace)]
6 public class NamespaceElement : ContainerItemElement {
6 public class NamespaceElement : ContainerItemElement {
7
7
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(ContainerContext context) {
11 public override void Visit(ContainerBuilder context) {
12 context.Visit(this);
12 context.Visit(this);
13 }
13 }
14 }
14 }
15 } No newline at end of file
15 }
@@ -1,19 +1,19
1 using System.Xml.Serialization;
1 using System.Xml.Serialization;
2
2
3 namespace Implab.ServiceHost.Unity {
3 namespace Implab.ServiceHost.Unity {
4 public class PropertyInjectionElement : AbstractInjectionElement {
4 public class PropertyInjectionElement : AbstractInjectionElement {
5
5
6 [XmlAttribute("name")]
6 [XmlAttribute("name")]
7 public string Name { get; set; }
7 public string Name { get; set; }
8
8
9 [XmlElement("dependency", typeof(DependencyParameterElement))]
9 [XmlElement("dependency", typeof(DependencyParameterElement))]
10 [XmlElement("value", typeof(ValueParameterElement))]
10 [XmlElement("value", typeof(ValueParameterElement))]
11 [XmlElement("serialized", typeof(SerializedParameterElement))]
11 [XmlElement("serialized", typeof(SerializedParameterElement))]
12 [XmlElement("default", typeof(DefaultParameterElement))]
12 [XmlElement("default", typeof(DefaultParameterElement))]
13 public InjectionParameterElement Value { get; set; }
13 public InjectionParameterElement Value { get; set; }
14
14
15 internal override void Visit(RegistrationContext context) {
15 internal override void Visit(TypeRegistrationBuilder context) {
16 context.Visit(this);
16 context.Visit(this);
17 }
17 }
18 }
18 }
19 } No newline at end of file
19 }
@@ -1,34 +1,28
1 using System;
1 using System;
2 using System.Xml.Serialization;
2 using System.Xml.Serialization;
3 using Unity.Lifetime;
3 using Unity.Lifetime;
4 using Unity.Registration;
4 using Unity.Registration;
5
5
6 namespace Implab.ServiceHost.Unity {
6 namespace Implab.ServiceHost.Unity {
7
7
8 [XmlRoot("register", Namespace = Schema.ContainerConfigurationNamespace)]
8 [XmlRoot("register", Namespace = Schema.ContainerConfigurationNamespace)]
9 public class RegisterElement : AbstractRegistration {
9 public class RegisterElement : AbstractRegistration {
10
10
11 /// <summary>
11 /// <summary>
12 /// An optional type which is registered as a service in the container, must be assignable to <see cref="ProvidesType">.
12 /// An optional type which is registered as a service in the container, must be assignable to <see cref="ProvidesType">.
13 /// </summary>
13 /// </summary>
14 [XmlAttribute("mapTo")]
14 [XmlAttribute("mapTo")]
15 public string MapToType { get; set; }
15 public string MapToType { get; set; }
16
16
17
17
18 [XmlElement("constructor", typeof(ConstructorInjectionElement))]
18 [XmlElement("constructor", typeof(ConstructorInjectionElement))]
19 [XmlElement("property", typeof(PropertyInjectionElement))]
19 [XmlElement("property", typeof(PropertyInjectionElement))]
20 [XmlElement("method", typeof(MethodInjectionElement))]
20 [XmlElement("method", typeof(MethodInjectionElement))]
21 public AbstractInjectionElement[] Injectors { get; set; }
21 public AbstractInjectionElement[] Injectors { get; set; }
22
22
23 public override void Visit(ContainerContext context) {
23 public override void Visit(ContainerBuilder context) {
24 context.Visit(this);
24 context.Visit(this);
25 }
25 }
26
27 public virtual Type ResolveImplementationType(ContainerContext ctx) {
28 return string.IsNullOrEmpty(MapToType) ?
29 ResolveRegistrationType(ctx) :
30 ctx.Resolve(MapToType);
31 }
32 }
26 }
33
27
34 } No newline at end of file
28 }
@@ -1,38 +1,37
1 using System;
1 using System;
2 using System.Xml;
2 using System.Xml;
3 using System.Xml.Serialization;
3 using System.Xml.Serialization;
4
4
5 namespace Implab.ServiceHost.Unity
5 namespace Implab.ServiceHost.Unity
6 {
6 {
7 public class SerializedElement : AbstractRegistration {
7 public class SerializedElement : AbstractRegistration, ISerializedValue {
8 [XmlAttribute("href")]
8 [XmlAttribute("href")]
9 public string Location { get; set; }
9 public string Location { get; set; }
10
10
11 [XmlAttribute("serializedType")]
11 [XmlAttribute("serializedType")]
12 public string SerializedType { get; set; }
12 public string SerializedType { get; set; }
13
13
14
14
15 [XmlAnyElement]
15 [XmlAnyElement]
16 public XmlElement[] Content { get; set; }
16 public XmlElement[] Content { get; set; }
17
17
18 public override void Visit(ContainerContext context) {
18 string ISerializedValue.TypeName {
19 get {
20 return string.IsNullOrEmpty(SerializedType) ? RegistrationType : SerializedType;
21 }
22 }
23
24 public override void Visit(ContainerBuilder context) {
19 context.Visit(this);
25 context.Visit(this);
20 }
26 }
21
27
22 public virtual Type ResolveSerializedType(ContainerContext context) {
28 public XmlReader GetReader() {
23 if(string.IsNullOrEmpty(SerializedType))
29 if (!string.IsNullOrEmpty(Location))
24 return ResolveRegistrationType(context);
30 return XmlReader.Create(Location);
25 return context.Resolve(SerializedType);
31 if (Content != null && Content.Length > 0)
26 }
32 return Content[0].CreateNavigator().ReadSubtree();
27
33
28 public virtual object GetValue(ContainerContext context) {
34 throw new Exception("No content found, expected XML document");
29 var type = ResolveRegistrationType(context);
30 if (Content == null || Content.Length == 0)
31 return Safe.CreateDefaultValue(type);
32
33 var serializer = new XmlSerializer(type);
34 using(var reader = Content[0].CreateNavigator().ReadSubtree())
35 return serializer.Deserialize(reader);
36 }
35 }
37 }
36 }
38 } No newline at end of file
37 }
@@ -1,18 +1,28
1 using System;
1 using System.Xml;
2 using System.Xml;
2 using System.Xml.Schema;
3 using System.Xml.Schema;
3 using System.Xml.Serialization;
4 using System.Xml.Serialization;
4
5
5 namespace Implab.ServiceHost.Unity
6 namespace Implab.ServiceHost.Unity
6 {
7 {
7 public class SerializedParameterElement : InjectionParameterElement {
8 public class SerializedParameterElement : InjectionParameterElement, ISerializedValue {
8 [XmlAttribute("href")]
9 [XmlAttribute("href")]
9 public string Location { get; set; }
10 public string Location { get; set; }
10
11
11 [XmlAnyElement]
12 [XmlAnyElement]
12 public XmlElement[] Content { get; set; }
13 public XmlElement[] Content { get; set; }
13
14
14 internal override object Resolve(RegistrationContext context) {
15 public XmlReader GetReader() {
15 return context.Resolve(this);
16 if (!string.IsNullOrEmpty(Location))
17 return XmlReader.Create(Location);
18 if (Content != null && Content.Length > 0)
19 return Content[0].CreateNavigator().ReadSubtree();
20
21 throw new Exception("No content found, expected XML document");
22 }
23
24 internal override void Visit(InjectionValueBuilder builder) {
25 builder.Visit(this);
16 }
26 }
17 }
27 }
18 } No newline at end of file
28 }
@@ -1,10 +1,10
1 using Unity.Lifetime;
1 using Unity.Lifetime;
2
2
3 namespace Implab.ServiceHost.Unity
3 namespace Implab.ServiceHost.Unity
4 {
4 {
5 public class SimgletonLifetimeElement : LifetimeElement {
5 public class SimgletonLifetimeElement : LifetimeElement {
6 public override LifetimeManager GetLifetimeManager(ContainerContext ctx) {
6 public override LifetimeManager GetLifetimeManager(ContainerBuilder ctx) {
7 return new SingletonLifetimeManager();
7 return new SingletonLifetimeManager();
8 }
8 }
9 }
9 }
10 } No newline at end of file
10 }
@@ -1,14 +1,28
1 using System.Xml.Serialization;
1 using System.Xml.Serialization;
2
2
3 namespace Implab.ServiceHost.Unity {
3 namespace Implab.ServiceHost.Unity {
4 public class ValueElement : AbstractRegistration, ITextValue {
4 public class ValueElement : AbstractRegistration, ITextValue {
5
5
6 [XmlText]
7 [XmlAttribute("value")]
6 [XmlAttribute("value")]
8 public string Value { get; set; }
7 public string Value { get; set; }
9
8
10 public override void Visit(ContainerContext context) {
9 [XmlText]
10 public string Text { get; set; }
11
12 string ITextValue.Value {
13 get {
14 return string.IsNullOrEmpty(Value) ? Text : Value;
15 }
16 }
17
18 public string TypeName {
19 get {
20 return RegistrationType;
21 }
22 }
23
24 public override void Visit(ContainerBuilder context) {
11 context.Visit(this);
25 context.Visit(this);
12 }
26 }
13 }
27 }
14 } No newline at end of file
28 }
@@ -1,15 +1,13
1 using System.Xml.Serialization;
1 using System.Xml.Serialization;
2
2
3 namespace Implab.ServiceHost.Unity
3 namespace Implab.ServiceHost.Unity {
4 {
4 public class ValueParameterElement : InjectionParameterElement, ITextValue {
5 public class ValueParameterElement : InjectionParameterElement
6 {
7 [XmlText]
5 [XmlText]
8 [XmlAttribute("value")]
6 [XmlAttribute("value")]
9 public string Value { get; set; }
7 public string Value { get; set; }
10
8
11 internal override object Resolve(RegistrationContext context) {
9 internal override void Visit(InjectionValueBuilder builder) {
12 return context.Resolve(this);
10 builder.Visit(this);
13 }
11 }
14 }
12 }
15 } No newline at end of file
13 }
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
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