Spring .Net Configuration Fluently
Asked Answered
M

6

3

I have the need to use Spring .Net in a project and am exploring configuration options. All I can find about config for Spring .Net is config file stuff. Does Spring support configuration in code? I have used Castle and Ninject, and both seem to offer this natively. I have found projects that claim to add support, but I dont want some knock off project that will die in 6 months. I have found references in blogs that seem to indicate Spring supports this but I cant find any documentation!!

Part 2 of this might be would you recommend Spring .Net over Windsor knowing it cant support fluent configuration? I know both are great IoC containers, but I have worked on projects that have massive config files for Spring configuration and I hate it.

Mccarty answered 29/12, 2010 at 23:2 Comment(2)
Are fluent-spring and spring-recoil the projects you found?Daveen
Spring.CodeConfig is now released so you might want to update your question nuget.org/List/Packages/Spring.CodeConfigCornaceous
B
11

No, the current version (1.3) of Spring.NET only supports XML configuration. There has been talk about supporting Code as Configuration in future versions, but this has not yet materialized.

In my opinion, Castle Windsor is far superior to Spring.NET. I can't think of a single feature of Spring.NET that Castle Windsor doesn't have. On the other hand, Castle Windsor has the following features that are not available in Spring.NET:

  • Code as Configuration
  • Convention-based configuration
  • More lifetimes
  • Custom lifetimes
  • Object graph decommissioning
  • Explicit mapping of interfaces/base classes to concrete types
  • Type-based resolution
  • Modular configuration (Installers)
  • Built-in support for Decorators
  • Typed Factories

There are probably other features I forgot about...


It appears I was a bit too quick on the trigger here, although to my defense, the Spring.NET documentation also states that there's only XML configuration in the current version.

However, it turns out that if for certain contexts, a very primitive API is available that enables you to configure a context without XML. Here's an example:

var context = new GenericApplicationContext();
context.RegisterObjectDefinition("EggYolk", 
    new RootObjectDefinition(typeof(EggYolk)));
context.RegisterObjectDefinition("OliveOil",
    new RootObjectDefinition(typeof(OliveOil)));
context.RegisterObjectDefinition("Mayonnaise", 
    new RootObjectDefinition(typeof(Mayonnaise), 
        AutoWiringMode.AutoDetect));

Notice how this API very closely mirrors the XML configuration schema. Thus, you don't get any fluent API from the IObjectDefinitionRegistry interface, but at least there's an API which is decoupled from XML. Building a fluent API on top of this is at least theoretically possible.

Bandur answered 30/12, 2010 at 8:30 Comment(3)
Hey thanks for the info! BTW the last update on your DI book was great... I cant wait to have my hard copy! Only missing the Spring chapter... which I needed ;-)Mccarty
not to mention sensible XML config if you need to use it, debugger diagnostics, Facilities (in general), and many other small featuresChamber
spring also supports automatic configuration via Autowire and configuration via Attributes instead of xml. Up to now i have only used the painful xml.Yuzik
N
5

You will find a fully working spring fluent API for spring.net on github:

https://github.com/thenapoleon/Fluent-API-for-Spring.Net

This API brings fluent configuration, and will soon support convention based configuration.

Noctiluca answered 20/2, 2011 at 13:28 Comment(0)
D
3

In answer to the first part of your question: the springsource team appears to be working on a code configuration project on github: https://github.com/SpringSource/spring-net-codeconfig. It was announced with (but not included in) the 1.3.1 (december 2010) release.

From the MovieFinder example:

[Configuration]
public class MovieFinderConfiguration
{

    [Definition]
    public virtual MovieLister MyMovieLister()
    {
        MovieLister movieLister =  new MovieLister();
        movieLister.MovieFinder = FileBasedMovieFinder();
        return movieLister;

    }

    [Definition]
    public virtual IMovieFinder FileBasedMovieFinder()
    {
        return new ColonDelimitedMovieFinder(new FileInfo("movies.txt"));
    }
}
Daveen answered 31/1, 2011 at 19:56 Comment(0)
M
3

There is another option using the Spring.AutoRegistration. The same concept used with Unity AutoRegistration.

https://www.nuget.org/packages/Spring.AutoRegistration

http://autoregistration.codeplex.com/

    var context = new GenericApplicationContext();
    context.Configure()
                .IncludeAssembly(x => x.FullName.StartsWith("Company.ApplicationXPTO"))
                .Include(x => x.ImplementsITypeName(), Then.Register().UsingSingleton()
                      .InjectByProperty(If.DecoratedWith<InjectAttribute>))
                .ApplyAutoRegistration();
Mercuri answered 6/12, 2012 at 4:11 Comment(0)
T
2

It is also possible to use Spring.FluentContext project.

With it, the configuration of MovieFinder would look as follows:

// Configuration
private static IApplicationContext Configure()
{
    var context = new FluentApplicationContext();

    context.RegisterDefault<MovieLister>()
            .BindProperty(l => l.MovieFinder).ToRegisteredDefaultOf<ColonDelimitedMovieFinder>();

    context.RegisterDefault<ColonDelimitedMovieFinder>()
            .UseConstructor((FileInfo fileInfo) => new ColonDelimitedMovieFinder(fileInfo))
            .BindConstructorArg().ToValue(new FileInfo("movies.txt"));

    return context;
}

// Usage
static void Main(string[] args)
{
    IApplicationContext context = Configure();

    var movieLister = context.GetObject<MovieLister>();

    foreach (var movie in movieLister.MoviesDirectedBy("Roberto Benigni"))
        Console.WriteLine(movie.Title);

    Console.ReadLine();
}

It does not require any hardcoded literal ID for objects (but allows that), it is type safe and contains documentation with samples on GitHub wiki.

Thereupon answered 28/6, 2013 at 12:59 Comment(0)
D
0

Using the Fluent-API-for-Spring.Net, the configuration could look something like:

    private void ConfigureMovieFinder()
    {

        FluentApplicationContext.Clear();

        FluentApplicationContext.Register<ColonDelimitedMovieFinder>("ColonDelimitedMovieFinder")
            .BindConstructorArgument<FileInfo>().To(new FileInfo("movies.txt"));

        // By default, fluent spring will create an identifier (Type.FullName) when using Register<T>()
        FluentApplicationContext.Register<MovieLister>()
            .Bind(x => x.MovieFinder).To<IMovieFinder>("ColonDelimitedMovieFinder");
    }
Daveen answered 11/3, 2011 at 16:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.