Cómo cambiar configuraciones en Spring.Net

Una ventaja de un contenedor IoC es que puede intercambiar un servicio simulado en la parte inferior de su gráfico de objetos. Sin embargo, esto parece mucho más difícil de hacer en Spring.Net que en otros Contenedores IoC. Aquí hay un código que lo hace en Unity y tiene el código de Spring.Net;

namespace IocSpringDemo
{
    using Microsoft.Practices.Unity;
    using NUnit.Framework;

    using Spring.Context;
    using Spring.Context.Support;

    public interface ISomeService
    {
        string DoSomething();
    }

    public class ServiceImplementationA : ISomeService
    {
        public string DoSomething()
        {
            return "Hello A";
        }
    }

    public class ServiceImplementationB : ISomeService
    {
        public string DoSomething()
        {
            return "Hello B";
        }
    }

    public class RootObject
    {
        public ISomeService SomeService { get; private set; }

        public RootObject(ISomeService service)
        {
            SomeService = service;
        }
    }

    [TestFixture]
    public class UnityAndSpringDemo
    {
        [Test]
        public void UnityResolveA()
        {
            UnityContainer container = new UnityContainer();
            container.RegisterType<ISomeService, ServiceImplementationA>();
            RootObject rootObject = container.Resolve<RootObject>();
            Assert.AreEqual("Hello A", rootObject.SomeService.DoSomething());
        }

        [Test]
        public void UnityResolveB()
        {
            UnityContainer container = new UnityContainer();
            container.RegisterType<ISomeService, ServiceImplementationB>();
            RootObject rootObject = container.Resolve<RootObject>();
            Assert.AreEqual("Hello B", rootObject.SomeService.DoSomething());
        }

        [Test]
        public void SpringResolveA()
        {
            IApplicationContext container = ContextRegistry.GetContext();
            RootObject rootObject = (RootObject)container.GetObject("RootObject");
            Assert.AreEqual("Hello A", rootObject.SomeService.DoSomething());
        }

        [Test]
        public void SpringResolveB()
        {
            // does not work - what to do to make this pass?
            IApplicationContext container = ContextRegistry.GetContext();
            RootObject rootObject = (RootObject)container.GetObject("RootObject");
            Assert.AreEqual("Hello B", rootObject.SomeService.DoSomething());
        }
    }
}

Para el beneficio de Spring, lo siguiente debe estar en el archivo App.config. Claramente esto solo sirve para la primera prueba de primavera, y no para la segunda. ¿Puedes poner múltiples configuraciones de resorte en el archivo de configuración? Si es así, ¿cuál es la sintaxis y cómo acceder a ellos? ¿O hay otra manera de hacer esto?

  <configSections>
    <sectionGroup name="spring">
      <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
      <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />
    </sectionGroup>
  </configSections>
  <spring>
    <context>
      <resource uri="config://spring/objects"/>
    </context>
    <objects xmlns="http://www.springframework.net">
      <object name="RootObject" type="IocSpringDemo.RootObject, IocDemo" autowire="constructor" />
      <object name="service" type="IocSpringDemo.ServiceImplementationA, IocDemo" autowire="constructor" />
    </objects>
  </spring>
Actualizar

Aquí hay una respuesta parcial basada en el código enLos enlaces que Marko Lahma le dio al blog de Mark Pollack.. Tengo las pruebas anteriores aprobadas, con el siguiente código:

public static class SpringHelper
{
    public static T Resolve<T>(this IApplicationContext context, string name)
    {
        return (T)context.GetObject(name);
    }

    public static void RegisterType<T>(this GenericApplicationContext context, string name)
    {
        context.RegisterType(name, typeof(T));
    }

    public static void RegisterType(this GenericApplicationContext context, string name, Type type)
    {
        IObjectDefinitionFactory objectDefinitionFactory = new DefaultObjectDefinitionFactory();
        ObjectDefinitionBuilder builder = ObjectDefinitionBuilder.RootObjectDefinition(objectDefinitionFactory, type);
        builder.SetAutowireMode(AutoWiringMode.AutoDetect);

        context.RegisterObjectDefinition(name, builder.ObjectDefinition);
    }
}

...

    [Test]
    public void SpringResolveA()
    {
        GenericApplicationContext container = new GenericApplicationContext();
        container.RegisterType<RootObject>("RootObject");
        container.RegisterType<ServiceImplementationA>("service");

        RootObject rootObject = container.Resolve<RootObject>("RootObject");
        Assert.AreEqual("Hello A", rootObject.SomeService.DoSomething());
    }

    [Test]
    public void SpringResolveB()
    {
        GenericApplicationContext container = new GenericApplicationContext();
        container.RegisterType<RootObject>("RootObject");
        container.RegisterType<ServiceImplementationB>("service");

        RootObject rootObject = container.Resolve<RootObject>("RootObject");
        Assert.AreEqual("Hello B", rootObject.SomeService.DoSomething());
    }

Esto me plantea algunas preguntas:

Quiero integrar esta técnica en el código existente que utiliza el contenedor habitual. ¿Por qué tengo que usar un tipo de contenedor diferente,GenericApplicationContext ¿en este caso? ¿Qué sucede si deseo leer datos en este objeto desde la configuración de Spring existente en app.config o web.config? ¿Funcionaría como el contexto habitual? ¿Podría entonces escribir datos sobre estos registros con código?

¿Cómo puedo especificar queISomeService ¿Se creará como un singleton? No me refiero a proporcionar una instancia de singleton al contenedor, sino al contenedor para crear la instancia, resolver su constructor y usarlo cuando se necesite ese tipo.

¿Cómo puedo hacer el equivalente decontainer.RegisterType<ISomeService, ServiceImplementationA>(); ? Quiero registrar asignaciones de tipo para usar en todos los casos en que un constructor necesite ese tipo.

Que hace exactamentecontainer.RegisterType<ServiceImplementationA>("service"); ¿hacer? Parece registrarseServiceImplementationA como la implementación deISomeService peroISomeServiceNunca se menciona, por lo que podría haber ambigüedad. p.ej. y siServiceImplementationA Implementado más de una interfaz.

¿Para qué se le da el nombre de la cadena al registro? No funcionará con una cadena vacía, pero no parece importar lo que sea.

¿Estoy tratando de usar la primavera de una manera que simplemente no funciona? Estoy tratando de usarlo como otros contenedores IoC, pero no está funcionando bien.

Respuestas a la pregunta(2)

Su respuesta a la pregunta