view Implab.ServiceHost/Unity/ContainerBuilder.cs @ 275:6fefd5811b9b v3

refactoring
author cin
date Fri, 27 Apr 2018 16:57:30 +0300
parents 22629bf26121
children 963b17c275be
line wrap: on
line source

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<ContainerBuilder>;

    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);
        }



    }
}