Как изменить конфиги в Spring.Net
Преимущество контейнера IoC заключается в том, что вы можете поменяться имитационной службой в нижней части графа объектов. Однако в Spring.Net это сделать гораздо сложнее, чем в других контейнерах IoC. Вот's некоторый код, который делает это в Unity и имеет код 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();
RootObject rootObject = container.Resolve();
Assert.AreEqual("Hello A", rootObject.SomeService.DoSomething());
}
[Test]
public void UnityResolveB()
{
UnityContainer container = new UnityContainer();
container.RegisterType();
RootObject rootObject = container.Resolve();
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());
}
}
}
Для удобства Spring в файле App.config должно быть указано следующее. Понятно, что это только первый весенний тест, а не второй. Можете ли вы поместить несколько конфигураций пружин в файл конфигурации? Если да, то каков синтаксис и как вы к ним обращаетесь? Или есть другой способ сделать это?
ОбновитьВот частичный ответ на основе кода вссылки, которые Марко Лахма дал Марку Поллакублог с, У меня есть вышеупомянутые тесты, проходящие со следующим кодом:
public static class SpringHelper
{
public static T Resolve(this IApplicationContext context, string name)
{
return (T)context.GetObject(name);
}
public static void RegisterType(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");
container.RegisterType("service");
RootObject rootObject = container.Resolve("RootObject");
Assert.AreEqual("Hello A", rootObject.SomeService.DoSomething());
}
[Test]
public void SpringResolveB()
{
GenericApplicationContext container = new GenericApplicationContext();
container.RegisterType("RootObject");
container.RegisterType("service");
RootObject rootObject = container.Resolve("RootObject");
Assert.AreEqual("Hello B", rootObject.SomeService.DoSomething());
}
Это поднимает мне несколько вопросов:
Я хочу интегрировать эту технику в существующий код, который использует обычный контейнер. Почему я должен использовать другой тип контейнера,GenericApplicationContext
в этом случае? Что если я захочу прочитать данные в этот объект из существующего весеннего конфига в app.config или web.config? Будет ли это работать в обычном контексте? Могу ли я тогда написать данные для этих регистраций с кодом?
Как я могу указать этоISomeService
должен быть создан как синглтон? Я неЭто означает, что нужно предоставить экземпляр-одиночку контейнеру, но контейнер, чтобы создать экземпляр, разрешить его конструктор и использовать его, когда нужен этот тип.
как я могу сделать эквивалентcontainer.RegisterType();
? Я хочу зарегистрировать сопоставления типов для использования во всех случаях, когда этот тип нужен конструктору.
Что именно делаетcontainer.RegisterType("service");
делать? Похоже на регистрациюServiceImplementationA
как реализацияISomeService
ноISomeService
никогда не упоминается, поэтому может быть двусмысленность. например что, еслиServiceImplementationA
реализовано более одного интерфейса.
Зачем нужно имя строки для регистрации? Это победилоне работает с пустой строкой, но это неКажется, не имеет значения, что это такое.
Пытаюсь ли я использовать пружину так, чтобы она просто не работала? Я'пытаюсь использовать его как другие контейнеры IoC, но этоне совсем работает.