Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to change configs in Spring.Net
    primarykey
    data
    text
    <p>An advantage of an IoC container is that you can swap in a mock service at the bottom of your object graph. However this seems much harder to do in Spring.Net than in other IoC Containers. Here's some code that does it in Unity and has Spring.Net code;</p> <pre><code>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&lt;ISomeService, ServiceImplementationA&gt;(); RootObject rootObject = container.Resolve&lt;RootObject&gt;(); Assert.AreEqual("Hello A", rootObject.SomeService.DoSomething()); } [Test] public void UnityResolveB() { UnityContainer container = new UnityContainer(); container.RegisterType&lt;ISomeService, ServiceImplementationB&gt;(); RootObject rootObject = container.Resolve&lt;RootObject&gt;(); 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()); } } } </code></pre> <p>For the benefit of Spring, the following needed to be in the App.config file. Clearly this only serves the first spring test, and not the second. Can you put multiple spring configurations in the config file? If so, what is the syntax and how do you access them? Or is there another way to do this?</p> <pre><code> &lt;configSections&gt; &lt;sectionGroup name="spring"&gt; &lt;section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/&gt; &lt;section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" /&gt; &lt;/sectionGroup&gt; &lt;/configSections&gt; &lt;spring&gt; &lt;context&gt; &lt;resource uri="config://spring/objects"/&gt; &lt;/context&gt; &lt;objects xmlns="http://www.springframework.net"&gt; &lt;object name="RootObject" type="IocSpringDemo.RootObject, IocDemo" autowire="constructor" /&gt; &lt;object name="service" type="IocSpringDemo.ServiceImplementationA, IocDemo" autowire="constructor" /&gt; &lt;/objects&gt; &lt;/spring&gt; </code></pre> <hr> <h2>Update</h2> <p>Here is a partial answer based at code at <a href="http://blog.springsource.com/2008/01/04/spring-net-11-and-container-configuration/" rel="nofollow noreferrer">the links that Marko Lahma gave to Mark Pollack's blog</a>. I have the above tests passing, with the following code:</p> <pre><code>public static class SpringHelper { public static T Resolve&lt;T&gt;(this IApplicationContext context, string name) { return (T)context.GetObject(name); } public static void RegisterType&lt;T&gt;(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); } } </code></pre> <p>...</p> <pre><code> [Test] public void SpringResolveA() { GenericApplicationContext container = new GenericApplicationContext(); container.RegisterType&lt;RootObject&gt;("RootObject"); container.RegisterType&lt;ServiceImplementationA&gt;("service"); RootObject rootObject = container.Resolve&lt;RootObject&gt;("RootObject"); Assert.AreEqual("Hello A", rootObject.SomeService.DoSomething()); } [Test] public void SpringResolveB() { GenericApplicationContext container = new GenericApplicationContext(); container.RegisterType&lt;RootObject&gt;("RootObject"); container.RegisterType&lt;ServiceImplementationB&gt;("service"); RootObject rootObject = container.Resolve&lt;RootObject&gt;("RootObject"); Assert.AreEqual("Hello B", rootObject.SomeService.DoSomething()); } </code></pre> <p>This raises a few questions to me:</p> <ul> <li><p>I want to integrate this technique into existing code that uses the usual container. Why do I have to use a different container type, <code>GenericApplicationContext</code> in this case? What if I want to read data into this object from the existing spring config in app.config or web.config? Would it work as the usual context? Could I then write data over these registrations with code? </p></li> <li><p>How can I specify that <code>ISomeService</code> is to be created as a singleton? I don't mean supply a singleton instance to the container, but the container to create the instance, resolving its constructor, and use it when that type is needed.</p></li> <li><p>how can I do the equivalent of <code>container.RegisterType&lt;ISomeService, ServiceImplementationA&gt;();</code> ? I want to register type mappings to use in all cases where that type is needed by a constructor.</p></li> <li><p>What exactly does <code>container.RegisterType&lt;ServiceImplementationA&gt;("service");</code> do? It seems to register <code>ServiceImplementationA</code> as the implementation of <code>ISomeService</code> but <code>ISomeService</code>is never mentioned, so there could be ambiguity. e.g. what if <code>ServiceImplementationA</code> implemented more than one interface.</p></li> <li><p>What is the string name given to the registration for? It won't work with en empty string, but it doesn't seem to matter what it is.</p></li> </ul> <p>Am I trying to use spring in a way that it just does not work? I'm trying to use it like other IoC containers, but it's not quite working.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload