# HG changeset patch
# User cin
# Date 2018-04-27 01:47:52
# Node ID 22629bf26121d959c790ef41a541f21a48c76ed7
# Parent 79110a16cab7c4b1cb503a2925b96021347870fa
Unity xml configuration, alpha2
diff --git a/Implab.Playground/Program.cs b/Implab.Playground/Program.cs
--- a/Implab.Playground/Program.cs
+++ b/Implab.Playground/Program.cs
@@ -50,7 +50,7 @@ namespace Implab.Playground {
var stopwatch = new Stopwatch();
stopwatch.Start();
- var ctx = new ContainerContext();
+ var ctx = new ContainerBuilder();
Console.WriteLine($"Created: {stopwatch.ElapsedMilliseconds}");
diff --git a/Implab.Playground/data/sample.xml b/Implab.Playground/data/sample.xml
--- a/Implab.Playground/data/sample.xml
+++ b/Implab.Playground/data/sample.xml
@@ -38,7 +38,7 @@
-
+
Baaar
diff --git a/Implab.ServiceHost/Unity/AbstractInjectionElement.cs b/Implab.ServiceHost/Unity/AbstractInjectionElement.cs
--- a/Implab.ServiceHost/Unity/AbstractInjectionElement.cs
+++ b/Implab.ServiceHost/Unity/AbstractInjectionElement.cs
@@ -1,8 +1,10 @@
using System;
-namespace Implab.ServiceHost.Unity
-{
+namespace Implab.ServiceHost.Unity {
+ ///
+ /// Base class for injections, each injection is applied to the type registration context.
+ ///
public abstract class AbstractInjectionElement {
- internal abstract void Visit(TypeRegistrationContext context);
+ internal abstract void Visit(TypeRegistrationBuilder context);
}
}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/AbstractRegistration.cs b/Implab.ServiceHost/Unity/AbstractRegistration.cs
--- a/Implab.ServiceHost/Unity/AbstractRegistration.cs
+++ b/Implab.ServiceHost/Unity/AbstractRegistration.cs
@@ -27,9 +27,5 @@ namespace Implab.ServiceHost.Unity
[XmlAttribute("type")]
public string RegistrationType { get; set; }
- public virtual Type ResolveRegistrationType(ContainerContext ctx) {
- return ctx.Resolve(RegistrationType);
- }
-
}
}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/AssemblyElement.cs b/Implab.ServiceHost/Unity/AssemblyElement.cs
--- a/Implab.ServiceHost/Unity/AssemblyElement.cs
+++ b/Implab.ServiceHost/Unity/AssemblyElement.cs
@@ -7,7 +7,7 @@ namespace Implab.ServiceHost.Unity
[XmlAttribute("name")]
public string AssemblyName { get; set; }
- public override void Visit(ContainerContext context) {
+ public override void Visit(ContainerBuilder context) {
context.Visit(this);
}
}
diff --git a/Implab.ServiceHost/Unity/ConstructorInjectionElement.cs b/Implab.ServiceHost/Unity/ConstructorInjectionElement.cs
--- a/Implab.ServiceHost/Unity/ConstructorInjectionElement.cs
+++ b/Implab.ServiceHost/Unity/ConstructorInjectionElement.cs
@@ -9,7 +9,7 @@ namespace Implab.ServiceHost.Unity {
[XmlElement("default", typeof(DefaultParameterElement))]
public InjectionParameterElement[] Parameters { get; set; }
- internal override void Visit(TypeRegistrationContext context) {
+ internal override void Visit(TypeRegistrationBuilder context) {
context.Visit(this);
}
}
diff --git a/Implab.ServiceHost/Unity/ContainerBuilder.cs b/Implab.ServiceHost/Unity/ContainerBuilder.cs
new file mode 100644
--- /dev/null
+++ b/Implab.ServiceHost/Unity/ContainerBuilder.cs
@@ -0,0 +1,125 @@
+using System;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using Implab.Diagnostics;
+
+namespace Implab.ServiceHost.Unity {
+ using System.Linq;
+ using System.Reflection;
+ using System.Text;
+ using global::Unity;
+ using global::Unity.Registration;
+ using Implab.Xml;
+ using static Trace;
+
+ public class ContainerBuilder {
+
+ readonly TypeResolver m_resolver;
+
+ readonly UnityContainer m_container;
+
+ readonly ContainerConfigurationSchema m_schema;
+
+ public UnityContainer Container {
+ get {
+ return m_container;
+ }
+ }
+
+ public ContainerBuilder() : this(null, null) {
+ }
+
+ public ContainerBuilder(UnityContainer container, ContainerConfigurationSchema schema) {
+ m_container = container ?? new UnityContainer();
+ m_resolver = new TypeResolver();
+ m_schema = schema ?? ContainerConfigurationSchema.Default;
+ }
+
+ public Type ResolveType(string typeReference) {
+ return m_resolver.Resolve(typeReference);
+ }
+
+ internal void Visit(RegisterElement registerElement) {
+ var registrationType = ResolveType(registerElement.RegistrationType);
+ var implementationType = string.IsNullOrEmpty(registerElement.MapToType) ? registrationType : ResolveType(registerElement.MapToType);
+
+ var registrationContext = new TypeRegistrationBuilder(
+ m_resolver,
+ registrationType,
+ implementationType
+ );
+
+ if (registerElement.Injectors != null) {
+ foreach (var injector in registerElement.Injectors) {
+ injector.Visit(registrationContext);
+ }
+ }
+
+ m_container.RegisterType(
+ registrationContext.RegistrationType,
+ registrationContext.ImplementationType,
+ registerElement.Name,
+ registerElement.Lifetime?.GetLifetimeManager(this),
+ registrationContext.Injections
+ );
+ }
+
+ internal void Visit(SerializedElement serializedElement) {
+ var registrationType = ResolveType(serializedElement.RegistrationType);
+ var valueBuilder = new InjectionValueBuilder(m_resolver, null);
+
+ valueBuilder.Visit(serializedElement);
+
+ m_container.RegisterInstance(
+ registrationType,
+ serializedElement.Name,
+ valueBuilder.Value,
+ serializedElement.Lifetime?.GetLifetimeManager(this)
+ );
+ }
+
+ internal void Visit(ValueElement valueElement) {
+ var registrationType = ResolveType(valueElement.RegistrationType);
+ var valueBuilder = new InjectionValueBuilder(m_resolver, null);
+
+ valueBuilder.Visit(valueElement);
+
+ m_container.RegisterInstance(
+ registrationType,
+ valueElement.Name,
+ valueBuilder.Value,
+ valueElement.Lifetime?.GetLifetimeManager(this)
+ );
+ }
+
+ internal void Visit(NamespaceElement namespaceElement) {
+ m_resolver.AddNamespace(namespaceElement.Name);
+ }
+
+ internal void Visit(AssemblyElement assemblyElement) {
+ Assembly.Load(assemblyElement.AssemblyName);
+ }
+
+ internal void Visit(IncludeElement includeElement) {
+ Include(includeElement.Href);
+ }
+
+ public void Include(string file) {
+ var includeContext = new ContainerBuilder(m_container, m_schema);
+ includeContext.LoadConfig(file);
+ }
+
+ public void LoadConfig(string file) {
+ var config = m_schema.LoadFile(file);
+ Visit(config);
+ }
+
+ internal void Visit(ContainerElement containerElement) {
+ foreach (var item in containerElement.Items)
+ item.Visit(this);
+ }
+
+
+
+ }
+}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/ContainerConfigurationSchema.cs b/Implab.ServiceHost/Unity/ContainerConfigurationSchema.cs
--- a/Implab.ServiceHost/Unity/ContainerConfigurationSchema.cs
+++ b/Implab.ServiceHost/Unity/ContainerConfigurationSchema.cs
@@ -55,6 +55,8 @@ namespace Implab.ServiceHost.Unity {
var schema = new ContainerConfigurationSchema();
schema.RegisterContainerElement("register");
+ schema.RegisterContainerElement("serialized");
+ schema.RegisterContainerElement("value");
schema.RegisterContainerElement("include");
schema.RegisterContainerElement("assembly");
schema.RegisterContainerElement("namespace");
diff --git a/Implab.ServiceHost/Unity/ContainerContext.cs b/Implab.ServiceHost/Unity/ContainerContext.cs
deleted file mode 100644
--- a/Implab.ServiceHost/Unity/ContainerContext.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text.RegularExpressions;
-using Implab.Diagnostics;
-
-namespace Implab.ServiceHost.Unity {
- using System.Linq;
- using System.Reflection;
- using System.Text;
- using global::Unity;
- using global::Unity.Registration;
- using Implab.Xml;
- using static Trace;
-
- public class ContainerContext {
-
- readonly TypeResolver m_resolver;
-
- readonly UnityContainer m_container;
-
- readonly ContainerConfigurationSchema m_schema;
-
- public UnityContainer Container {
- get {
- return m_container;
- }
- }
-
- public ContainerContext() : this(null, null) {
- }
-
- public ContainerContext(UnityContainer container, ContainerConfigurationSchema schema) {
- m_container = container ?? new UnityContainer();
- m_resolver = new TypeResolver();
- m_schema = schema ?? ContainerConfigurationSchema.Default;
- }
-
- public Type Resolve(string typeReference) {
- return m_resolver.Resolve(typeReference);
- }
-
- internal void Visit(RegisterElement registerElement) {
- var registrationContext = new TypeRegistrationContext(
- m_resolver,
- registerElement.ResolveRegistrationType(this),
- registerElement.ResolveImplementationType(this)
- );
-
- if (registerElement.Injectors != null) {
- foreach (var injector in registerElement.Injectors) {
- injector.Visit(registrationContext);
- }
- }
-
- m_container.RegisterType(
- registrationContext.RegistrationType,
- registrationContext.ImplementationType,
- registerElement.Name,
- registerElement.Lifetime?.GetLifetimeManager(this),
- registrationContext.Injections
- );
- }
-
- internal void Visit(SerializedElement serializedElement) {
- var registrationType = serializedElement.ResolveRegistrationType(this);
- var instace = serializedElement.GetValue(this);
-
-
- m_container.RegisterInstance(
- registrationType,
- serializedElement.Name,
- instace,
- serializedElement.Lifetime?.GetLifetimeManager(this)
- );
- }
-
- internal void Visit(ValueElement valueElement) {
-
- }
-
- internal void Visit(NamespaceElement namespaceElement) {
- m_resolver.AddNamespace(namespaceElement.Name);
- }
-
- internal void Visit(AssemblyElement assemblyElement) {
- Assembly.Load(assemblyElement.AssemblyName);
- }
-
- internal void Visit(IncludeElement includeElement) {
- Include(includeElement.Href);
- }
-
- public void Include(string file) {
- var includeContext = new ContainerContext(m_container, m_schema);
- includeContext.LoadConfig(file);
- }
-
- public void LoadConfig(string file) {
- var config = m_schema.LoadFile(file);
- Visit(config);
- }
-
- internal void Visit(ContainerElement containerElement) {
- foreach (var item in containerElement.Items)
- item.Visit(this);
- }
-
-
-
- }
-}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/ContainerElement.cs b/Implab.ServiceHost/Unity/ContainerElement.cs
--- a/Implab.ServiceHost/Unity/ContainerElement.cs
+++ b/Implab.ServiceHost/Unity/ContainerElement.cs
@@ -8,9 +8,9 @@ namespace Implab.ServiceHost.Unity {
[XmlRoot("container", Namespace = Schema.ContainerConfigurationNamespace)]
public class ContainerElement : ContainerItemElement {
- public List Items {get; set; } = new List();
+ public List Items { get; set; } = new List();
- public override void Visit(ContainerContext context) {
+ public override void Visit(ContainerBuilder context) {
context.Visit(this);
}
}
diff --git a/Implab.ServiceHost/Unity/ContainerItemElement.cs b/Implab.ServiceHost/Unity/ContainerItemElement.cs
--- a/Implab.ServiceHost/Unity/ContainerItemElement.cs
+++ b/Implab.ServiceHost/Unity/ContainerItemElement.cs
@@ -1,5 +1,5 @@
namespace Implab.ServiceHost.Unity {
public abstract class ContainerItemElement {
- public abstract void Visit(ContainerContext context);
+ public abstract void Visit(ContainerBuilder context);
}
}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/ContainerLifetimeElement.cs b/Implab.ServiceHost/Unity/ContainerLifetimeElement.cs
--- a/Implab.ServiceHost/Unity/ContainerLifetimeElement.cs
+++ b/Implab.ServiceHost/Unity/ContainerLifetimeElement.cs
@@ -3,7 +3,7 @@ using Unity.Lifetime;
namespace Implab.ServiceHost.Unity
{
public class ContainerLifetimeElement : LifetimeElement {
- public override LifetimeManager GetLifetimeManager(ContainerContext ctx) {
+ public override LifetimeManager GetLifetimeManager(ContainerBuilder ctx) {
return new ContainerControlledLifetimeManager();
}
}
diff --git a/Implab.ServiceHost/Unity/ContextLifetimeElement.cs b/Implab.ServiceHost/Unity/ContextLifetimeElement.cs
--- a/Implab.ServiceHost/Unity/ContextLifetimeElement.cs
+++ b/Implab.ServiceHost/Unity/ContextLifetimeElement.cs
@@ -3,7 +3,7 @@ using Unity.Lifetime;
namespace Implab.ServiceHost.Unity
{
public class ContextLifetimeElement : LifetimeElement {
- public override LifetimeManager GetLifetimeManager(ContainerContext ctx) {
+ public override LifetimeManager GetLifetimeManager(ContainerBuilder ctx) {
return new PerResolveLifetimeManager();
}
}
diff --git a/Implab.ServiceHost/Unity/DefaultParameterElement.cs b/Implab.ServiceHost/Unity/DefaultParameterElement.cs
--- a/Implab.ServiceHost/Unity/DefaultParameterElement.cs
+++ b/Implab.ServiceHost/Unity/DefaultParameterElement.cs
@@ -1,9 +1,12 @@
namespace Implab.ServiceHost.Unity
{
- public class DefaultParameterElement : InjectionParameterElement {
- internal override object Resolve(InjectionValueContext context) {
- var type = context.ResolveType(TypeName);
- return Safe.CreateDefaultValue(type);
+ public class DefaultParameterElement : InjectionParameterElement, ITextValue {
+ public string Value {
+ get { return null; }
+ }
+
+ internal override void Visit(InjectionValueBuilder builder) {
+ builder.Visit(this);
}
}
}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/DependencyParameterElement.cs b/Implab.ServiceHost/Unity/DependencyParameterElement.cs
--- a/Implab.ServiceHost/Unity/DependencyParameterElement.cs
+++ b/Implab.ServiceHost/Unity/DependencyParameterElement.cs
@@ -1,12 +1,16 @@
using System.Xml.Serialization;
namespace Implab.ServiceHost.Unity {
- public class DependencyParameterElement : InjectionParameterElement {
+ public class DependencyParameterElement : InjectionParameterElement, IDependencyReference {
[XmlAttribute("name")]
public string DependencyName { get; set; }
[XmlAttribute("optional")]
public bool Optional { get; set; }
+
+ internal override void Visit(InjectionValueBuilder builder) {
+ builder.Visit(this);
+ }
}
}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/FactoryInjectionElement.cs b/Implab.ServiceHost/Unity/FactoryInjectionElement.cs
new file mode 100644
--- /dev/null
+++ b/Implab.ServiceHost/Unity/FactoryInjectionElement.cs
@@ -0,0 +1,7 @@
+namespace Implab.ServiceHost.Unity {
+ public class FactoryInjectionElement : AbstractInjectionElement {
+ internal override void Visit(TypeRegistrationBuilder context) {
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/HierarchicalLifetimeElement.cs b/Implab.ServiceHost/Unity/HierarchicalLifetimeElement.cs
--- a/Implab.ServiceHost/Unity/HierarchicalLifetimeElement.cs
+++ b/Implab.ServiceHost/Unity/HierarchicalLifetimeElement.cs
@@ -3,7 +3,7 @@ using Unity.Lifetime;
namespace Implab.ServiceHost.Unity
{
public class HierarchicalLifetimeElement : LifetimeElement {
- public override LifetimeManager GetLifetimeManager(ContainerContext ctx) {
+ public override LifetimeManager GetLifetimeManager(ContainerBuilder ctx) {
return new HierarchicalLifetimeManager();
}
}
diff --git a/Implab.ServiceHost/Unity/IDependencyReference.cs b/Implab.ServiceHost/Unity/IDependencyReference.cs
--- a/Implab.ServiceHost/Unity/IDependencyReference.cs
+++ b/Implab.ServiceHost/Unity/IDependencyReference.cs
@@ -1,5 +1,8 @@
namespace Implab.ServiceHost.Unity {
public interface IDependencyReference {
- string Name { get; set; }
+
+ string TypeName { get; set; }
+
+ string DependencyName { get; set; }
}
}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/ISerializedValue.cs b/Implab.ServiceHost/Unity/ISerializedValue.cs
--- a/Implab.ServiceHost/Unity/ISerializedValue.cs
+++ b/Implab.ServiceHost/Unity/ISerializedValue.cs
@@ -1,7 +1,11 @@
-namespace Implab.ServiceHost.Unity
-{
- public class ISerializedValue
- {
-
+using System.Xml;
+
+namespace Implab.ServiceHost.Unity {
+ public interface ISerializedValue {
+
+ string TypeName { get; }
+
+ XmlReader GetReader();
+
}
}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/ITextValue.cs b/Implab.ServiceHost/Unity/ITextValue.cs
--- a/Implab.ServiceHost/Unity/ITextValue.cs
+++ b/Implab.ServiceHost/Unity/ITextValue.cs
@@ -1,5 +1,7 @@
namespace Implab.ServiceHost.Unity {
public interface ITextValue {
+ string TypeName { get; }
+
string Value { get; }
}
diff --git a/Implab.ServiceHost/Unity/IncludeElement.cs b/Implab.ServiceHost/Unity/IncludeElement.cs
--- a/Implab.ServiceHost/Unity/IncludeElement.cs
+++ b/Implab.ServiceHost/Unity/IncludeElement.cs
@@ -6,7 +6,7 @@ namespace Implab.ServiceHost.Unity {
[XmlAttribute("href")]
public string Href { get; set; }
- public override void Visit(ContainerContext context) {
+ public override void Visit(ContainerBuilder context) {
context.Visit(this);
}
}
diff --git a/Implab.ServiceHost/Unity/InjectionParameterElement.cs b/Implab.ServiceHost/Unity/InjectionParameterElement.cs
--- a/Implab.ServiceHost/Unity/InjectionParameterElement.cs
+++ b/Implab.ServiceHost/Unity/InjectionParameterElement.cs
@@ -7,10 +7,6 @@ namespace Implab.ServiceHost.Unity {
[XmlAttribute("type")]
public string TypeName { get; set; }
- internal abstract object Resolve(InjectionValueContext context);
-
- public virtual Type ResolveParameterType(InjectionValueContext context) {
- return context.ResolveType(TypeName);
- }
+ internal abstract void Visit(InjectionValueBuilder builder);
}
}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/InjectionValueBuilder.cs b/Implab.ServiceHost/Unity/InjectionValueBuilder.cs
new file mode 100644
--- /dev/null
+++ b/Implab.ServiceHost/Unity/InjectionValueBuilder.cs
@@ -0,0 +1,64 @@
+using System;
+using System.ComponentModel;
+using System.Xml.Serialization;
+using Unity.Injection;
+
+namespace Implab.ServiceHost.Unity {
+
+ public class InjectionValueBuilder {
+
+ readonly TypeResolver m_resolver;
+
+ public Type DefaultType { get; private set; }
+
+ public Type ValueType { get; set; }
+
+ public object Value { get; set; }
+
+ public InjectionParameterValue Injection {
+ get {
+ if (Value != null)
+ return InjectionParameterValue.ToParameter(Value);
+
+ return new InjectionParameter(ValueType, null);
+ }
+ }
+
+ internal InjectionValueBuilder(TypeResolver resolver, Type acceptsType) {
+ m_resolver = resolver;
+ DefaultType = acceptsType;
+ }
+
+ public Type ResolveType(string typeSpec) {
+ if (string.IsNullOrEmpty(typeSpec)) {
+ if (DefaultType == null)
+ throw new Exception("The type must be specified");
+ return DefaultType;
+ }
+ return m_resolver.Resolve(typeSpec);
+ }
+
+ public void Visit(ITextValue value) {
+ ValueType = ResolveType(value.TypeName);
+
+ Value = string.IsNullOrEmpty(value.Value) ?
+ Safe.CreateDefaultValue(ValueType) :
+ TypeDescriptor.GetConverter(ValueType).ConvertFromString(value.Value);
+ }
+
+ public void Visit(ISerializedValue value) {
+ ValueType = ResolveType(value.TypeName);
+
+ var serializer = new XmlSerializer(ValueType);
+
+ using (var reader = value.GetReader())
+ Value = new InjectionParameter(ValueType, serializer.Deserialize(reader));
+ }
+
+ public void Visit(IDependencyReference value) {
+ ValueType = ResolveType(value.TypeName);
+ Value = new ResolvedParameter(ValueType, value.DependencyName);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/InjectionValueContext.cs b/Implab.ServiceHost/Unity/InjectionValueContext.cs
deleted file mode 100644
--- a/Implab.ServiceHost/Unity/InjectionValueContext.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using System;
-using Unity.Injection;
-
-namespace Implab.ServiceHost.Unity {
-
- public class InjectionValueContext {
-
- readonly TypeResolver m_resolver;
-
- public Type AcceptsType { get; private set; }
-
- public object Value { get; set; }
-
- internal InjectionValueContext(TypeResolver resolver, Type acceptsType) {
- m_resolver = resolver;
- AcceptsType = acceptsType;
- }
-
- public Type ResolveType(string typeSpec) {
- if (string.IsNullOrEmpty(typeSpec)) {
- if (AcceptsType == null)
- throw new Exception("The type must be specified");
- return AcceptsType;
- }
- return m_resolver.Resolve(typeSpec);
- }
-
- public void Visit(ITextValue value) {
-
- }
-
- public void Visit(ISerializedValue value) {
-
- }
-
- public void Visit(IDependencyReference value) {
- Value = new ResolvedParameter()
- }
-
- }
-}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/InstanceRegistrationContext.cs b/Implab.ServiceHost/Unity/InstanceRegistrationContext.cs
deleted file mode 100644
--- a/Implab.ServiceHost/Unity/InstanceRegistrationContext.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-
-namespace Implab.ServiceHost.Unity {
- public class InstanceRegistrationContext : RegistrationContext {
-
- readonly TypeResolver m_typeResolver;
- public override TypeResolver Resolver { get { return m_typeResolver; } }
-
- public InstanceRegistrationContext(TypeResolver resolver, Type registrationType) : base(registrationType) {
- Safe.ArgumentNotNull(resolver, nameof(resolver));
- m_typeResolver = resolver;
- }
-
-
- }
-}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/LifetimeElement.cs b/Implab.ServiceHost/Unity/LifetimeElement.cs
--- a/Implab.ServiceHost/Unity/LifetimeElement.cs
+++ b/Implab.ServiceHost/Unity/LifetimeElement.cs
@@ -4,7 +4,7 @@ namespace Implab.ServiceHost.Unity
{
public abstract class LifetimeElement
{
- public abstract LifetimeManager GetLifetimeManager(ContainerContext ctx);
+ public abstract LifetimeManager GetLifetimeManager(ContainerBuilder ctx);
}
}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/MethodInjectionElement.cs b/Implab.ServiceHost/Unity/MethodInjectionElement.cs
--- a/Implab.ServiceHost/Unity/MethodInjectionElement.cs
+++ b/Implab.ServiceHost/Unity/MethodInjectionElement.cs
@@ -12,7 +12,7 @@ namespace Implab.ServiceHost.Unity {
[XmlElement("default", typeof(DefaultParameterElement))]
public InjectionParameterElement[] Parameters { get; set; }
- internal override void Visit(RegistrationContext context) {
+ internal override void Visit(TypeRegistrationBuilder context) {
context.Visit(this);
}
}
diff --git a/Implab.ServiceHost/Unity/NamespaceElement.cs b/Implab.ServiceHost/Unity/NamespaceElement.cs
--- a/Implab.ServiceHost/Unity/NamespaceElement.cs
+++ b/Implab.ServiceHost/Unity/NamespaceElement.cs
@@ -8,7 +8,7 @@ namespace Implab.ServiceHost.Unity
[XmlAttribute("name")]
public string Name { get; set; }
- public override void Visit(ContainerContext context) {
+ public override void Visit(ContainerBuilder context) {
context.Visit(this);
}
}
diff --git a/Implab.ServiceHost/Unity/PropertyInjectionElement.cs b/Implab.ServiceHost/Unity/PropertyInjectionElement.cs
--- a/Implab.ServiceHost/Unity/PropertyInjectionElement.cs
+++ b/Implab.ServiceHost/Unity/PropertyInjectionElement.cs
@@ -12,7 +12,7 @@ namespace Implab.ServiceHost.Unity {
[XmlElement("default", typeof(DefaultParameterElement))]
public InjectionParameterElement Value { get; set; }
- internal override void Visit(RegistrationContext context) {
+ internal override void Visit(TypeRegistrationBuilder context) {
context.Visit(this);
}
}
diff --git a/Implab.ServiceHost/Unity/RegisterElement.cs b/Implab.ServiceHost/Unity/RegisterElement.cs
--- a/Implab.ServiceHost/Unity/RegisterElement.cs
+++ b/Implab.ServiceHost/Unity/RegisterElement.cs
@@ -20,15 +20,9 @@ namespace Implab.ServiceHost.Unity {
[XmlElement("method", typeof(MethodInjectionElement))]
public AbstractInjectionElement[] Injectors { get; set; }
- public override void Visit(ContainerContext context) {
+ public override void Visit(ContainerBuilder context) {
context.Visit(this);
}
-
- public virtual Type ResolveImplementationType(ContainerContext ctx) {
- return string.IsNullOrEmpty(MapToType) ?
- ResolveRegistrationType(ctx) :
- ctx.Resolve(MapToType);
- }
}
}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/RegistrationBuilder.cs b/Implab.ServiceHost/Unity/RegistrationBuilder.cs
new file mode 100644
--- /dev/null
+++ b/Implab.ServiceHost/Unity/RegistrationBuilder.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Xml.Serialization;
+using Implab.Xml;
+using Unity.Injection;
+using Unity.Registration;
+
+namespace Implab.ServiceHost.Unity {
+ public abstract class RegistrationBuilder {
+ public Type RegistrationType {
+ get;
+ private set;
+ }
+
+ protected RegistrationBuilder(Type registrationType) {
+ RegistrationType = registrationType;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/RegistrationContext.cs b/Implab.ServiceHost/Unity/RegistrationContext.cs
deleted file mode 100644
--- a/Implab.ServiceHost/Unity/RegistrationContext.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.Xml.Serialization;
-using Implab.Xml;
-using Unity.Injection;
-using Unity.Registration;
-
-namespace Implab.ServiceHost.Unity {
- public abstract class RegistrationContext {
- public Type RegistrationType {
- get;
- private set;
- }
-
- protected RegistrationContext(Type registrationType) {
- RegistrationType = registrationType;
- }
- }
-}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/SerializedElement.cs b/Implab.ServiceHost/Unity/SerializedElement.cs
--- a/Implab.ServiceHost/Unity/SerializedElement.cs
+++ b/Implab.ServiceHost/Unity/SerializedElement.cs
@@ -4,7 +4,7 @@ using System.Xml.Serialization;
namespace Implab.ServiceHost.Unity
{
- public class SerializedElement : AbstractRegistration {
+ public class SerializedElement : AbstractRegistration, ISerializedValue {
[XmlAttribute("href")]
public string Location { get; set; }
@@ -14,25 +14,24 @@ namespace Implab.ServiceHost.Unity
[XmlAnyElement]
public XmlElement[] Content { get; set; }
-
- public override void Visit(ContainerContext context) {
+
+ string ISerializedValue.TypeName {
+ get {
+ return string.IsNullOrEmpty(SerializedType) ? RegistrationType : SerializedType;
+ }
+ }
+
+ public override void Visit(ContainerBuilder context) {
context.Visit(this);
}
- public virtual Type ResolveSerializedType(ContainerContext context) {
- if(string.IsNullOrEmpty(SerializedType))
- return ResolveRegistrationType(context);
- return context.Resolve(SerializedType);
- }
+ public XmlReader GetReader() {
+ if (!string.IsNullOrEmpty(Location))
+ return XmlReader.Create(Location);
+ if (Content != null && Content.Length > 0)
+ return Content[0].CreateNavigator().ReadSubtree();
- public virtual object GetValue(ContainerContext context) {
- var type = ResolveRegistrationType(context);
- if (Content == null || Content.Length == 0)
- return Safe.CreateDefaultValue(type);
-
- var serializer = new XmlSerializer(type);
- using(var reader = Content[0].CreateNavigator().ReadSubtree())
- return serializer.Deserialize(reader);
+ throw new Exception("No content found, expected XML document");
}
}
}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/SerializedParameterElement.cs b/Implab.ServiceHost/Unity/SerializedParameterElement.cs
--- a/Implab.ServiceHost/Unity/SerializedParameterElement.cs
+++ b/Implab.ServiceHost/Unity/SerializedParameterElement.cs
@@ -1,18 +1,28 @@
+using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
namespace Implab.ServiceHost.Unity
{
- public class SerializedParameterElement : InjectionParameterElement {
+ public class SerializedParameterElement : InjectionParameterElement, ISerializedValue {
[XmlAttribute("href")]
public string Location { get; set; }
[XmlAnyElement]
public XmlElement[] Content { get; set; }
- internal override object Resolve(RegistrationContext context) {
- return context.Resolve(this);
+ public XmlReader GetReader() {
+ if (!string.IsNullOrEmpty(Location))
+ return XmlReader.Create(Location);
+ if (Content != null && Content.Length > 0)
+ return Content[0].CreateNavigator().ReadSubtree();
+
+ throw new Exception("No content found, expected XML document");
+ }
+
+ internal override void Visit(InjectionValueBuilder builder) {
+ builder.Visit(this);
}
}
}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/SimgletonLifetimeElement.cs b/Implab.ServiceHost/Unity/SimgletonLifetimeElement.cs
--- a/Implab.ServiceHost/Unity/SimgletonLifetimeElement.cs
+++ b/Implab.ServiceHost/Unity/SimgletonLifetimeElement.cs
@@ -3,7 +3,7 @@ using Unity.Lifetime;
namespace Implab.ServiceHost.Unity
{
public class SimgletonLifetimeElement : LifetimeElement {
- public override LifetimeManager GetLifetimeManager(ContainerContext ctx) {
+ public override LifetimeManager GetLifetimeManager(ContainerBuilder ctx) {
return new SingletonLifetimeManager();
}
}
diff --git a/Implab.ServiceHost/Unity/TypeRegistrationBuilder.cs b/Implab.ServiceHost/Unity/TypeRegistrationBuilder.cs
new file mode 100644
--- /dev/null
+++ b/Implab.ServiceHost/Unity/TypeRegistrationBuilder.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Unity.Injection;
+using Unity.Registration;
+
+namespace Implab.ServiceHost.Unity {
+ public class TypeRegistrationBuilder : RegistrationBuilder {
+
+ readonly TypeResolver m_resolver;
+
+ readonly List m_injections = new List();
+
+ public InjectionMember[] Injections { get { return m_injections.ToArray(); } }
+
+ public Type ImplementationType {
+ get;
+ private set;
+ }
+
+ internal TypeRegistrationBuilder(TypeResolver resolver, Type registrationType, Type implementationType) : base(registrationType) {
+ ImplementationType = implementationType;
+
+ // when registering a generic mapping, register all generic parameter names as local types
+ if (ImplementationType.IsGenericTypeDefinition) {
+ m_resolver = new TypeResolver(resolver);
+
+ foreach (var p in ImplementationType.GetGenericArguments())
+ m_resolver.AddMapping(p.Name, p);
+ } else {
+ m_resolver = resolver;
+ }
+ }
+
+ internal void Visit(ConstructorInjectionElement constructorInjection) {
+
+
+ var parameters = constructorInjection.Parameters?
+ .Select(x => {
+ var valueBuilder = new InjectionValueBuilder(m_resolver, null);
+ x.Visit(valueBuilder);
+ return valueBuilder.Injection;
+ })
+ .ToArray();
+
+ var injection = parameters != null ? new InjectionConstructor(parameters) : new InjectionConstructor();
+ m_injections.Add(injection);
+ }
+
+ internal void Visit(MethodInjectionElement methodInjection) {
+ var valueContext = new InjectionValueBuilder(m_resolver, null);
+
+ var parameters = methodInjection.Parameters?
+ .Select(x => {
+ var valueBuilder = new InjectionValueBuilder(m_resolver, null);
+ x.Visit(valueBuilder);
+ return valueBuilder.Injection;
+ })
+ .ToArray();
+
+ var injection = parameters != null ? new InjectionMethod(methodInjection.Name, parameters) : new InjectionMethod(methodInjection.Name);
+ m_injections.Add(injection);
+ }
+
+ internal void Visit(PropertyInjectionElement propertyInjection) {
+ if (propertyInjection.Value == null)
+ throw new Exception($"A value value must be specified for the property '{propertyInjection.Name}'");
+
+ var propertyType = RegistrationType.GetProperty(propertyInjection.Name)?.PropertyType;
+ var valueContext = new InjectionValueBuilder(m_resolver, propertyType);
+
+ propertyInjection.Value.Visit(valueContext);
+ var injection = new InjectionProperty(propertyInjection.Name, valueContext.Injection);
+ m_injections.Add(injection);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/TypeRegistrationContext.cs b/Implab.ServiceHost/Unity/TypeRegistrationContext.cs
deleted file mode 100644
--- a/Implab.ServiceHost/Unity/TypeRegistrationContext.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Unity.Injection;
-using Unity.Registration;
-
-namespace Implab.ServiceHost.Unity {
- public class TypeRegistrationContext : RegistrationContext {
-
- readonly TypeResolver m_resolver;
-
- readonly List m_injections = new List();
-
- public InjectionMember[] Injections { get { return m_injections.ToArray(); } }
-
- public Type ImplementationType {
- get;
- private set;
- }
-
- internal TypeRegistrationContext(TypeResolver resolver, Type registrationType, Type implementationType) : base(registrationType) {
- ImplementationType = implementationType;
-
- // when registering a generic mapping, register all generic parameter names as local types
- if (ImplementationType.IsGenericTypeDefinition) {
- m_resolver = new TypeResolver(resolver);
-
- foreach (var p in ImplementationType.GetGenericArguments())
- m_resolver.AddMapping(p.Name, p);
- } else {
- m_resolver = resolver;
- }
- }
-
- internal void Visit(ConstructorInjectionElement constructorInjection) {
- var valueContext = new InjectionValueContext(m_resolver, null);
-
- var parameters = constructorInjection.Parameters?.Select(x => x.Resolve(valueContext)).ToArray();
-
- var injection = parameters != null ? new InjectionConstructor(parameters) : new InjectionConstructor();
- m_injections.Add(injection);
- }
-
- internal void Visit(MethodInjectionElement methodInjection) {
- var valueContext = new InjectionValueContext(m_resolver, null);
-
- var parameters = methodInjection.Parameters?.Select(x => x.Resolve(valueContext)).ToArray();
-
- var injection = parameters != null ? new InjectionMethod(methodInjection.Name, parameters) : new InjectionMethod(methodInjection.Name);
- m_injections.Add(injection);
- }
-
- internal void Visit(PropertyInjectionElement propertyInjection) {
- if (propertyInjection.Value == null)
- throw new Exception($"A value value must be specified for the property '{propertyInjection.Name}'");
-
- var propertyType = RegistrationType.GetProperty(propertyInjection.Name)?.PropertyType;
- var valueContext = new InjectionValueContext(m_resolver, propertyType);
-
- var parameter = propertyInjection.Value.Resolve(valueContext);
- var injection = new InjectionProperty(propertyInjection.Name, parameter);
- m_injections.Add(injection);
- }
- }
-}
\ No newline at end of file
diff --git a/Implab.ServiceHost/Unity/ValueElement.cs b/Implab.ServiceHost/Unity/ValueElement.cs
--- a/Implab.ServiceHost/Unity/ValueElement.cs
+++ b/Implab.ServiceHost/Unity/ValueElement.cs
@@ -3,11 +3,25 @@ using System.Xml.Serialization;
namespace Implab.ServiceHost.Unity {
public class ValueElement : AbstractRegistration, ITextValue {
- [XmlText]
[XmlAttribute("value")]
public string Value { get; set; }
- public override void Visit(ContainerContext context) {
+ [XmlText]
+ public string Text { get; set; }
+
+ string ITextValue.Value {
+ get {
+ return string.IsNullOrEmpty(Value) ? Text : Value;
+ }
+ }
+
+ public string TypeName {
+ get {
+ return RegistrationType;
+ }
+ }
+
+ public override void Visit(ContainerBuilder context) {
context.Visit(this);
}
}
diff --git a/Implab.ServiceHost/Unity/ValueParameterElement.cs b/Implab.ServiceHost/Unity/ValueParameterElement.cs
--- a/Implab.ServiceHost/Unity/ValueParameterElement.cs
+++ b/Implab.ServiceHost/Unity/ValueParameterElement.cs
@@ -1,15 +1,13 @@
using System.Xml.Serialization;
-namespace Implab.ServiceHost.Unity
-{
- public class ValueParameterElement : InjectionParameterElement
- {
+namespace Implab.ServiceHost.Unity {
+ public class ValueParameterElement : InjectionParameterElement, ITextValue {
[XmlText]
[XmlAttribute("value")]
public string Value { get; set; }
- internal override object Resolve(RegistrationContext context) {
- return context.Resolve(this);
+ internal override void Visit(InjectionValueBuilder builder) {
+ builder.Visit(this);
}
}
}
\ No newline at end of file