##// END OF EJS Templates
Working on Unity xml configuration: Refactoring in progress
cin -
r273:79110a16cab7 v3
parent child
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -0,0 +1,67
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Reflection;
5 using System.Xml;
6 using System.Xml.Serialization;
7 using Implab.Components;
8
9 namespace Implab.ServiceHost.Unity {
10 public class ContainerConfigurationSchema {
11
12 public static ContainerConfigurationSchema Default { get; private set; } = CreateDefault();
13
14 readonly LazyAndWeak<XmlSerializer> m_seralizer;
15
16 readonly XmlAttributeOverrides m_overrides = new XmlAttributeOverrides();
17
18 readonly XmlAttributes m_containerItems = new XmlAttributes();
19
20 public XmlSerializer Serializer {
21 get {
22 return m_seralizer.Value;
23 }
24 }
25
26 public ContainerConfigurationSchema() {
27 m_overrides.Add(typeof(ContainerElement), nameof(ContainerElement.Items), m_containerItems);
28
29 m_seralizer = new LazyAndWeak<XmlSerializer>(() => new XmlSerializer(typeof(ContainerElement), m_overrides));
30 }
31
32 public void RegisterContainerElement(Type type, string name) {
33 Safe.ArgumentNotNull(type, nameof(type));
34 Safe.ArgumentNotEmpty(name, nameof(name));
35
36 if(!type.IsSubclassOf(typeof(ContainerItemElement)))
37 throw new Exception($"RegisterContainerElement '{name}': {type} must be subclass of {typeof(ContainerItemElement)}");
38
39 m_containerItems.XmlElements.Add(
40 new XmlElementAttribute(name, type)
41 );
42 }
43
44 public void RegisterContainerElement<T>(string name) where T : ContainerItemElement {
45 RegisterContainerElement(typeof(T), name);
46 }
47
48 public ContainerElement LoadFile(string file) {
49 using (var reader = XmlReader.Create(file)) {
50 return (ContainerElement)Serializer.Deserialize(reader);
51 }
52 }
53
54 static ContainerConfigurationSchema CreateDefault() {
55 var schema = new ContainerConfigurationSchema();
56
57 schema.RegisterContainerElement<RegisterElement>("register");
58 schema.RegisterContainerElement<IncludeElement>("include");
59 schema.RegisterContainerElement<AssemblyElement>("assembly");
60 schema.RegisterContainerElement<NamespaceElement>("namespace");
61
62 return schema;
63 }
64
65
66 }
67 } No newline at end of file
@@ -0,0 +1,111
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<ContainerContext>;
14
15 public class ContainerContext {
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 ContainerContext() : this(null, null) {
30 }
31
32 public ContainerContext(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 Resolve(string typeReference) {
39 return m_resolver.Resolve(typeReference);
40 }
41
42 internal void Visit(RegisterElement registerElement) {
43 var registrationContext = new TypeRegistrationContext(
44 m_resolver,
45 registerElement.ResolveRegistrationType(this),
46 registerElement.ResolveImplementationType(this)
47 );
48
49 if (registerElement.Injectors != null) {
50 foreach (var injector in registerElement.Injectors) {
51 injector.Visit(registrationContext);
52 }
53 }
54
55 m_container.RegisterType(
56 registrationContext.RegistrationType,
57 registrationContext.ImplementationType,
58 registerElement.Name,
59 registerElement.Lifetime?.GetLifetimeManager(this),
60 registrationContext.Injections
61 );
62 }
63
64 internal void Visit(SerializedElement serializedElement) {
65 var registrationType = serializedElement.ResolveRegistrationType(this);
66 var instace = serializedElement.GetValue(this);
67
68
69 m_container.RegisterInstance(
70 registrationType,
71 serializedElement.Name,
72 instace,
73 serializedElement.Lifetime?.GetLifetimeManager(this)
74 );
75 }
76
77 internal void Visit(ValueElement valueElement) {
78
79 }
80
81 internal void Visit(NamespaceElement namespaceElement) {
82 m_resolver.AddNamespace(namespaceElement.Name);
83 }
84
85 internal void Visit(AssemblyElement assemblyElement) {
86 Assembly.Load(assemblyElement.AssemblyName);
87 }
88
89 internal void Visit(IncludeElement includeElement) {
90 Include(includeElement.Href);
91 }
92
93 public void Include(string file) {
94 var includeContext = new ContainerContext(m_container, m_schema);
95 includeContext.LoadConfig(file);
96 }
97
98 public void LoadConfig(string file) {
99 var config = m_schema.LoadFile(file);
100 Visit(config);
101 }
102
103 internal void Visit(ContainerElement containerElement) {
104 foreach (var item in containerElement.Items)
105 item.Visit(this);
106 }
107
108
109
110 }
111 } No newline at end of file
@@ -0,0 +1,5
1 namespace Implab.ServiceHost.Unity {
2 public abstract class ContainerItemElement {
3 public abstract void Visit(ContainerContext context);
4 }
5 } No newline at end of file
@@ -0,0 +1,5
1 namespace Implab.ServiceHost.Unity {
2 public interface IDependencyReference {
3 string Name { get; set; }
4 }
5 } No newline at end of file
@@ -0,0 +1,7
1 namespace Implab.ServiceHost.Unity
2 {
3 public class ISerializedValue
4 {
5
6 }
7 } No newline at end of file
@@ -0,0 +1,6
1 namespace Implab.ServiceHost.Unity {
2 public interface ITextValue {
3 string Value { get; }
4
5 }
6 } No newline at end of file
@@ -0,0 +1,41
1 using System;
2 using Unity.Injection;
3
4 namespace Implab.ServiceHost.Unity {
5
6 public class InjectionValueContext {
7
8 readonly TypeResolver m_resolver;
9
10 public Type AcceptsType { get; private set; }
11
12 public object Value { get; set; }
13
14 internal InjectionValueContext(TypeResolver resolver, Type acceptsType) {
15 m_resolver = resolver;
16 AcceptsType = acceptsType;
17 }
18
19 public Type ResolveType(string typeSpec) {
20 if (string.IsNullOrEmpty(typeSpec)) {
21 if (AcceptsType == null)
22 throw new Exception("The type must be specified");
23 return AcceptsType;
24 }
25 return m_resolver.Resolve(typeSpec);
26 }
27
28 public void Visit(ITextValue value) {
29
30 }
31
32 public void Visit(ISerializedValue value) {
33
34 }
35
36 public void Visit(IDependencyReference value) {
37 Value = new ResolvedParameter()
38 }
39
40 }
41 } No newline at end of file
@@ -0,0 +1,16
1 using System;
2
3 namespace Implab.ServiceHost.Unity {
4 public class InstanceRegistrationContext : RegistrationContext {
5
6 readonly TypeResolver m_typeResolver;
7 public override TypeResolver Resolver { get { return m_typeResolver; } }
8
9 public InstanceRegistrationContext(TypeResolver resolver, Type registrationType) : base(registrationType) {
10 Safe.ArgumentNotNull(resolver, nameof(resolver));
11 m_typeResolver = resolver;
12 }
13
14
15 }
16 } No newline at end of file
@@ -0,0 +1,38
1 using System;
2 using System.Xml;
3 using System.Xml.Serialization;
4
5 namespace Implab.ServiceHost.Unity
6 {
7 public class SerializedElement : AbstractRegistration {
8 [XmlAttribute("href")]
9 public string Location { get; set; }
10
11 [XmlAttribute("serializedType")]
12 public string SerializedType { get; set; }
13
14
15 [XmlAnyElement]
16 public XmlElement[] Content { get; set; }
17
18 public override void Visit(ContainerContext context) {
19 context.Visit(this);
20 }
21
22 public virtual Type ResolveSerializedType(ContainerContext context) {
23 if(string.IsNullOrEmpty(SerializedType))
24 return ResolveRegistrationType(context);
25 return context.Resolve(SerializedType);
26 }
27
28 public virtual object GetValue(ContainerContext context) {
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 }
37 }
38 } No newline at end of file
@@ -0,0 +1,65
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 TypeRegistrationContext : RegistrationContext {
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 TypeRegistrationContext(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 var valueContext = new InjectionValueContext(m_resolver, null);
37
38 var parameters = constructorInjection.Parameters?.Select(x => x.Resolve(valueContext)).ToArray();
39
40 var injection = parameters != null ? new InjectionConstructor(parameters) : new InjectionConstructor();
41 m_injections.Add(injection);
42 }
43
44 internal void Visit(MethodInjectionElement methodInjection) {
45 var valueContext = new InjectionValueContext(m_resolver, null);
46
47 var parameters = methodInjection.Parameters?.Select(x => x.Resolve(valueContext)).ToArray();
48
49 var injection = parameters != null ? new InjectionMethod(methodInjection.Name, parameters) : new InjectionMethod(methodInjection.Name);
50 m_injections.Add(injection);
51 }
52
53 internal void Visit(PropertyInjectionElement propertyInjection) {
54 if (propertyInjection.Value == null)
55 throw new Exception($"A value value must be specified for the property '{propertyInjection.Name}'");
56
57 var propertyType = RegistrationType.GetProperty(propertyInjection.Name)?.PropertyType;
58 var valueContext = new InjectionValueContext(m_resolver, propertyType);
59
60 var parameter = propertyInjection.Value.Resolve(valueContext);
61 var injection = new InjectionProperty(propertyInjection.Name, parameter);
62 m_injections.Add(injection);
63 }
64 }
65 } No newline at end of file
@@ -0,0 +1,14
1 using System.Xml.Serialization;
2
3 namespace Implab.ServiceHost.Unity {
4 public class ValueElement : AbstractRegistration, ITextValue {
5
6 [XmlText]
7 [XmlAttribute("value")]
8 public string Value { get; set; }
9
10 public override void Visit(ContainerContext context) {
11 context.Visit(this);
12 }
13 }
14 } No newline at end of file
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
@@ -47,19 +47,28 namespace Implab.Playground {
47 public class Program {
47 public class Program {
48
48
49 static void Main(string[] args) {
49 static void Main(string[] args) {
50 var container = new UnityContainer();
50 var stopwatch = new Stopwatch();
51 stopwatch.Start();
51
52
52 var ctx = new ConfigurationContext(container);
53 var ctx = new ContainerContext();
54
55 Console.WriteLine($"Created: {stopwatch.ElapsedMilliseconds}");
56
57 ctx.LoadConfig("data/sample.xml");
53
58
54 var conf = SerializationHelpers.DeserializeFromFile<ContainerElement>("data/sample.xml");
59 Console.WriteLine($"Loaded: {stopwatch.ElapsedMilliseconds}");
60
61 var container = ctx.Container;
62
63
55
64
56 ctx.Visit(conf);
65 var instace1 = container.Resolve<IContainer<string>>();
66 Console.WriteLine($"Resolved1: {stopwatch.ElapsedMilliseconds}");
67 var instace2 = container.Resolve<IContainer<Foo>>();
68
69 Console.WriteLine($"Resolved2: {stopwatch.ElapsedMilliseconds}");
57
70
58 DisplayContainerRegistrations(container);
71 DisplayContainerRegistrations(container);
59
60 var instace1 = container.Resolve<IContainer<string>>();
61 var instace2 = container.Resolve<IContainer<Foo>>();
62
63 }
72 }
64
73
65 static void DisplayContainerRegistrations(IUnityContainer theContainer) {
74 static void DisplayContainerRegistrations(IUnityContainer theContainer) {
@@ -23,18 +23,27
23 <register type="Foo">
23 <register type="Foo">
24 </register>
24 </register>
25
25
26 <register provides="IContainer{}" type="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 provides="IContainer{String}" type="Container{String}">
33 <register type="IContainer{String}" mapTo="Container{String}">
34 <constructor/>
34 <constructor/>
35 <method name="SetInstance">
35 <method name="SetInstance">
36 <value type="String">Hello!</value>
36 <dependency type="String" name="name1"/>
37 </method>
37 </method>
38 </register>
38 </register>
39
39
40 <serialized type="Foo+Bar">
41 <Bar id="1">
42 <Name>Baaar</Name>
43 </Bar>
44 </serialized>
45
46 <value name="connection1" type="String"><![CDATA[Connect me <here>!]]></value>
47 <value name="name1" type="String" value="Hello!"/>
48
40 </container> No newline at end of file
49 </container>
@@ -3,6 +3,6 using System;
3 namespace Implab.ServiceHost.Unity
3 namespace Implab.ServiceHost.Unity
4 {
4 {
5 public abstract class AbstractInjectionElement {
5 public abstract class AbstractInjectionElement {
6 internal abstract void Visit(RegistrationContext context);
6 internal abstract void Visit(TypeRegistrationContext context);
7 }
7 }
8 } No newline at end of file
8 }
@@ -5,7 +5,7 using Unity.Registration;
5
5
6 namespace Implab.ServiceHost.Unity
6 namespace Implab.ServiceHost.Unity
7 {
7 {
8 public abstract class AbstractRegistration : IConfigurationElement {
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
@@ -24,9 +24,12 namespace Implab.ServiceHost.Unity
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("provides")]
27 [XmlAttribute("type")]
28 public string ProvidesType { get; set; }
28 public string RegistrationType { get; set; }
29
29
30 public abstract void Visit(ConfigurationContext context);
30 public virtual Type ResolveRegistrationType(ContainerContext ctx) {
31 return ctx.Resolve(RegistrationType);
32 }
33
31 }
34 }
32 } No newline at end of file
35 }
@@ -3,11 +3,11 using System.Xml.Serialization;
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 : IConfigurationElement {
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 void Visit(ConfigurationContext context) {
10 public override void Visit(ContainerContext context) {
11 context.Visit(this);
11 context.Visit(this);
12 }
12 }
13 }
13 }
@@ -9,7 +9,7 namespace Implab.ServiceHost.Unity {
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(RegistrationContext context) {
12 internal override void Visit(TypeRegistrationContext context) {
13 context.Visit(this);
13 context.Visit(this);
14 }
14 }
15 }
15 }
@@ -6,26 +6,12 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 : IXmlSerializable {
9 public class ContainerElement : ContainerItemElement {
10
11 public List<IConfigurationElement> Items {get; set; } = new List<IConfigurationElement>();
12
13 public XmlSchema GetSchema() {
14 return null;
15 }
16
10
17 public void ReadXml(XmlReader reader) {
11 public List<ContainerItemElement> Items {get; set; } = new List<ContainerItemElement>();
18 while(reader.Read() && reader.NodeType != XmlNodeType.EndElement) {
19 var registration = ConfigurationSchema.Default.Deserialize<IConfigurationElement>(reader);
20 Items.Add(registration);
21 }
22 }
23
12
24 public void WriteXml(XmlWriter writer) {
13 public override void Visit(ContainerContext context) {
25 foreach(var item in Items) {
14 context.Visit(this);
26 var serializer = new XmlSerializer(item.GetType());
27 serializer.Serialize(writer, item);
28 }
29 }
15 }
30 }
16 }
31 } No newline at end of file
17 }
@@ -3,7 +3,7 using Unity.Lifetime;
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(ConfigurationContext ctx) {
6 public override LifetimeManager GetLifetimeManager(ContainerContext ctx) {
7 return new ContainerControlledLifetimeManager();
7 return new ContainerControlledLifetimeManager();
8 }
8 }
9 }
9 }
@@ -3,7 +3,7 using Unity.Lifetime;
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(ConfigurationContext ctx) {
6 public override LifetimeManager GetLifetimeManager(ContainerContext ctx) {
7 return new PerResolveLifetimeManager();
7 return new PerResolveLifetimeManager();
8 }
8 }
9 }
9 }
@@ -1,8 +1,9
1 namespace Implab.ServiceHost.Unity
1 namespace Implab.ServiceHost.Unity
2 {
2 {
3 public class DefaultParameterElement : InjectionParameterElement {
3 public class DefaultParameterElement : InjectionParameterElement {
4 internal override object Resolve(RegistrationContext context) {
4 internal override object Resolve(InjectionValueContext context) {
5 return context.Resolve(this);
5 var type = context.ResolveType(TypeName);
6 return Safe.CreateDefaultValue(type);
6 }
7 }
7 }
8 }
8 } No newline at end of file
9 }
@@ -8,9 +8,5 namespace Implab.ServiceHost.Unity {
8
8
9 [XmlAttribute("optional")]
9 [XmlAttribute("optional")]
10 public bool Optional { get; set; }
10 public bool Optional { get; set; }
11
12 internal override object Resolve(RegistrationContext context) {
13 return context.Resolve(this);
14 }
15 }
11 }
16 } No newline at end of file
12 }
@@ -3,7 +3,7 using Unity.Lifetime;
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(ConfigurationContext ctx) {
6 public override LifetimeManager GetLifetimeManager(ContainerContext ctx) {
7 return new HierarchicalLifetimeManager();
7 return new HierarchicalLifetimeManager();
8 }
8 }
9 }
9 }
@@ -2,11 +2,11 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 : IConfigurationElement {
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 void Visit(ConfigurationContext context) {
9 public override void Visit(ContainerContext context) {
10 context.Visit(this);
10 context.Visit(this);
11 }
11 }
12 }
12 }
@@ -1,3 +1,4
1 using System;
1 using System.Xml.Serialization;
2 using System.Xml.Serialization;
2
3
3 namespace Implab.ServiceHost.Unity {
4 namespace Implab.ServiceHost.Unity {
@@ -6,6 +7,10 namespace Implab.ServiceHost.Unity {
6 [XmlAttribute("type")]
7 [XmlAttribute("type")]
7 public string TypeName { get; set; }
8 public string TypeName { get; set; }
8
9
9 internal abstract object Resolve(RegistrationContext context);
10 internal abstract object Resolve(InjectionValueContext context);
11
12 public virtual Type ResolveParameterType(InjectionValueContext context) {
13 return context.ResolveType(TypeName);
14 }
10 }
15 }
11 } No newline at end of file
16 }
@@ -4,7 +4,7 namespace Implab.ServiceHost.Unity
4 {
4 {
5 public abstract class LifetimeElement
5 public abstract class LifetimeElement
6 {
6 {
7 public abstract LifetimeManager GetLifetimeManager(ConfigurationContext ctx);
7 public abstract LifetimeManager GetLifetimeManager(ContainerContext ctx);
8
8
9 }
9 }
10 } No newline at end of file
10 }
@@ -3,12 +3,12 using System.Xml.Serialization;
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 : IConfigurationElement {
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 void Visit(ConfigurationContext context) {
11 public override void Visit(ContainerContext context) {
12 context.Visit(this);
12 context.Visit(this);
13 }
13 }
14 }
14 }
@@ -11,8 +11,8 namespace Implab.ServiceHost.Unity {
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("type")]
14 [XmlAttribute("mapTo")]
15 public string ImplementationType { get; set; }
15 public string MapToType { get; set; }
16
16
17
17
18 [XmlElement("constructor", typeof(ConstructorInjectionElement))]
18 [XmlElement("constructor", typeof(ConstructorInjectionElement))]
@@ -20,9 +20,15 namespace Implab.ServiceHost.Unity {
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(ConfigurationContext context) {
23 public override void Visit(ContainerContext 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 }
26 }
32 }
27
33
28 } No newline at end of file
34 }
@@ -8,112 +8,14 using Unity.Injection;
8 using Unity.Registration;
8 using Unity.Registration;
9
9
10 namespace Implab.ServiceHost.Unity {
10 namespace Implab.ServiceHost.Unity {
11 class RegistrationContext {
11 public abstract class RegistrationContext {
12 readonly TypeResolver m_resolver;
13
14 List<InjectionMember> m_injections = new List<InjectionMember>();
15
16 Type m_defaultType;
17
18 public Type RegistrationType {
12 public Type RegistrationType {
19 get;
13 get;
20 private set;
14 private set;
21 }
15 }
22
16
23 public Type ImplementationType {
17 protected RegistrationContext(Type registrationType) {
24 get;
18 RegistrationType = registrationType;
25 private set;
26 }
27
28 public RegistrationContext(TypeResolver resolver, string typeSpec, string implSpec) {
29 RegistrationType = resolver.Resolve(string.IsNullOrEmpty(typeSpec) ? implSpec : typeSpec);
30
31
32 ImplementationType = string.IsNullOrEmpty(implSpec) ? RegistrationType : resolver.Resolve(implSpec);
33
34 if (RegistrationType.IsGenericTypeDefinition) {
35 m_resolver = new TypeResolver(resolver);
36
37 foreach (var p in ImplementationType.GetGenericArguments())
38 m_resolver.AddMapping(p.Name, p);
39 } else {
40 m_resolver = resolver;
41 }
42
43
44 }
45
46 public InjectionMember[] Injections {
47 get {
48 return m_injections.ToArray();
49 }
50 }
51
52 public void Visit(ConstructorInjectionElement constructorInjection) {
53 var parameters = constructorInjection.Parameters?.Select(x => x.Resolve(this)).ToArray();
54
55 var injection = parameters != null ? new InjectionConstructor(parameters) : new InjectionConstructor();
56 m_injections.Add(injection);
57 }
58
59 public void Visit(MethodInjectionElement methodInjection) {
60 var parameters = methodInjection.Parameters?.Select(x => x.Resolve(this)).ToArray();
61
62 var injection = parameters != null ? new InjectionMethod(methodInjection.Name, parameters) : new InjectionMethod(methodInjection.Name);
63 m_injections.Add(injection);
64 }
65
66 public void Visit(PropertyInjectionElement propertyInjection) {
67 if (propertyInjection.Value == null)
68 throw new Exception($"A value value must be specified for the property '{propertyInjection.Name}'");
69
70 try {
71 m_defaultType = RegistrationType.GetProperty(propertyInjection.Name)?.PropertyType;
72
73 var parameter = propertyInjection.Value.Resolve(this);
74 var injection = new InjectionProperty(propertyInjection.Name, parameter);
75 m_injections.Add(injection);
76
77 } finally {
78 m_defaultType = null;
79 }
80
81 }
82
83 Type ResolveParameterType(InjectionParameterElement injectionParameter) {
84 if (string.IsNullOrEmpty(injectionParameter.TypeName)) {
85 if (m_defaultType == null)
86 throw new Exception($"A type must be specified for the parameter {injectionParameter}");
87 return m_defaultType;
88 }
89 return m_resolver.Resolve(injectionParameter.TypeName);
90 }
91
92 public object Resolve(DefaultParameterElement defaultParameter) {
93 var type = ResolveParameterType(defaultParameter);
94
95 return Safe.CreateDefaultValue(type);
96 }
97
98 public object Resolve(ValueParameterElement valueParameter) {
99 var type = ResolveParameterType(valueParameter);
100
101 return TypeDescriptor.GetConverter(type).ConvertFromString(valueParameter.Value);
102 }
103
104 public object Resolve(SerializedParameterElement serializedParameter) {
105 var type = ResolveParameterType(serializedParameter);
106 if (serializedParameter.Content == null || serializedParameter.Content.Length == 0)
107 return Safe.CreateDefaultValue(type);
108
109 var serializer = new XmlSerializer(type);
110 using (var reader = serializedParameter.Content[0].CreateNavigator().ReadSubtree())
111 return serializer.Deserialize(reader);
112 }
113
114 public InjectionParameterValue Resolve(DependencyParameterElement dependencyParameter) {
115 var type = ResolveParameterType(dependencyParameter);
116 return new ResolvedParameter(type, dependencyParameter.DependencyName);
117 }
19 }
118 }
20 }
119 } No newline at end of file
21 }
@@ -5,6 +5,8 using System.Xml.Serialization;
5 namespace Implab.ServiceHost.Unity
5 namespace Implab.ServiceHost.Unity
6 {
6 {
7 public class SerializedParameterElement : InjectionParameterElement {
7 public class SerializedParameterElement : InjectionParameterElement {
8 [XmlAttribute("href")]
9 public string Location { get; set; }
8
10
9 [XmlAnyElement]
11 [XmlAnyElement]
10 public XmlElement[] Content { get; set; }
12 public XmlElement[] Content { get; set; }
@@ -3,7 +3,7 using Unity.Lifetime;
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(ConfigurationContext ctx) {
6 public override LifetimeManager GetLifetimeManager(ContainerContext ctx) {
7 return new SingletonLifetimeManager();
7 return new SingletonLifetimeManager();
8 }
8 }
9 }
9 }
@@ -5,6 +5,7 namespace Implab.ServiceHost.Unity
5 public class ValueParameterElement : InjectionParameterElement
5 public class ValueParameterElement : InjectionParameterElement
6 {
6 {
7 [XmlText]
7 [XmlText]
8 [XmlAttribute("value")]
8 public string Value { get; set; }
9 public string Value { get; set; }
9
10
10 internal override object Resolve(RegistrationContext context) {
11 internal override object Resolve(RegistrationContext context) {
@@ -1,4 +1,4
1 XML to JSON transform is taken from different project https://hg.implab.org/pub/ModelGenerator/
1 XML to JSON transform is taken from the different project https://hg.implab.org/pub/ModelGenerator/
2 run:
2 run:
3 wget https://hg.implab.org/pub/ModelGenerator/raw-file/tip/xslt/json.xsl
3 wget https://hg.implab.org/pub/ModelGenerator/raw-file/tip/xslt/json.xsl
4 to update to the latest version No newline at end of file
4 to update it to the latest version No newline at end of file
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