【问题标题】:Spring .Net Configuration FluentlySpring .Net 配置流利
【发布时间】:2010-12-29 23:02:59
【问题描述】:

我需要在项目中使用 Spring .Net,并且正在探索配置选项。我能找到的关于 Spring .Net 配置的所有信息都是配置文件。 Spring 是否支持代码中的配置?我用过 Castle 和 Ninject,两者似乎都提供了这个。我找到了声称要增加支持的项目,但我不想要一些会在 6 个月内死掉的仿冒项目。我在博客中找到了似乎表明 Spring 支持这一点的参考资料,但我找不到任何文档!!

第 2 部分可能是您是否会推荐 Spring .Net 而不是 Windsor,因为它不能支持流畅的配置?我知道这两个都是很棒的 IoC 容器,但是我参与过包含大量 Spring 配置文件的项目,我讨厌它。

【问题讨论】:

标签: dependency-injection ioc-container spring.net


【解决方案1】:

不,Spring.NET 的当前版本(1.3)仅支持 XML 配置。已经讨论过在未来的版本中支持代码即配置,但这还没有实现。

在我看来,Castle Windsor 远优于 Spring.NET。我想不出Castle Windsor 没有的Spring.NET 的单一功能。另一方面,Castle Windsor 具有以下 Spring.NET 中没有的功能:

  • 代码即配置
  • 基于约定的配置
  • 更多生命周期
  • 自定义生命周期
  • 对象图退役
  • 接口/基类到具体类型的显式映射
  • 基于类型的分辨率
  • 模块化配置(安装程序)
  • 对装饰器的内置支持
  • 类型化工厂

可能还有其他我忘记的功能......


看来我在这里触发有点太快了,尽管为了我的辩护,Spring.NET 文档还指出当前版本中只有 XML 配置。

然而,事实证明,如果对于 某些 上下文,可以使用非常原始的 API,使您能够在没有 XML 的情况下配置上下文。这是一个例子:

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

请注意此 API 如何非常接近地反映 XML 配置模式。因此,您不会从IObjectDefinitionRegistry 接口获得任何流畅的API,但至少有一个与XML 分离的API。在此之上构建流畅的 API 至少在理论上是可行的。

【讨论】:

  • 您好,感谢您提供的信息!顺便说一句,你的 DI 书的最后一次更新很棒……我等不及要我的硬拷贝了!只是缺少春季章节......我需要;-)
  • 更不用说如果您需要使用合理的 XML 配置、调试器诊断、设施(一般)和许多其他小功能
  • spring 还支持通过Autowire 自动配置和通过Attributes 配置而不是xml。到目前为止,我只使用了痛苦的 xml。
【解决方案2】:

您将在 github 上找到一个用于 spring.net 的完全可用的 spring fluent API:

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

这个API带来了流畅的配置,很快就会支持基于约定的配置。

【讨论】:

    【解决方案3】:

    回答您问题的第一部分:springsource 团队似乎正在 github 上进行代码配置项目:https://github.com/SpringSource/spring-net-codeconfig。它在 1.3.1(2010 年 12 月)版本中发布(但未包含在其中)。

    来自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"));
        }
    }
    

    【讨论】:

      【解决方案4】:

      还有另一个使用 Spring.AutoRegistration 的选项。与 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();
      

      【讨论】:

        【解决方案5】:

        也可以使用Spring.FluentContext项目。

        有了它,MovieFinder 的配置如下:

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

        它不需要任何硬编码的对象文字 ID(但允许这样做),它是类型安全的,并且包含 GitHub wiki 上的示例文档。

        【讨论】:

          【解决方案6】:

          使用Fluent-API-for-Spring.Net,配置可能类似于:

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

          【讨论】:

            猜你喜欢
            • 2019-09-06
            • 2019-02-21
            • 1970-01-01
            • 1970-01-01
            • 2017-03-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-12-14
            相关资源
            最近更新 更多