【问题标题】:Compile time support for AutofacAutofac 的编译时支持
【发布时间】:2012-12-05 17:53:36
【问题描述】:

我们为我们的项目调查 DI 容器。现在我们在 Autofac 和 Castle Windsor 之间进行选择。有一点对我们来说非常重要:Autofac 的强类型注册。

例子:

public interface ITestAutofac
{        
}

public class NotDerivedFrom
{        
}

对于温莎,我可以写这样的东西-

var cont = new WindsorContainer();

cont.Register(Component
    .For<ITestAutofac>().ImplementedBy<NotDerivedFrom>());

它会在编译时失败。 Resharper 可以很容易地在这方面提供帮助。

对于 Autofac,我可以这样写 -

builder.Register(c => new NotDerivedFrom()).As<ITestAutofac>();

var form = container.Resolve<ICustomForm>();

它会在运行时失败。

如何在 Autofac 中注册类型并进行编译时检查?

【问题讨论】:

    标签: c# .net castle-windsor autofac strong-typing


    【解决方案1】:
    builder.Register<NotDerivedFrom>().As<ITestAutofac>()
    

    使用 Autofac 时,这将在运行时失败,但是当您调用 builder.Build() 时会发生这种情况,当您考虑这一点时,这并不是很糟糕。我同意,它没有编译时支持那么好,但你可以找到一个调用builder.Build() 的单元测试。不要忘记大多数 DI 配置错误无论如何都无法被编译器捕获,您需要您的容器 a verifiable configuration 和一些单元测试来查找所有配置错误。

    如何在 Autofac 中注册类型并进行编译时检查?

    如果你愿意,你可以写一个简单的扩展方法来增加编译时检查:

    public static void Register<TService, TImplementation>(
        this ContainerBuilder builder)
        // Note the generic type constraints here
        where TImplementation: class, TService
        where TService: class
    {
        builder.Register<TImplementation>().As<TService>();
    }
    

    这使您可以按如下方式进行原始注册:

    build.Register<ITestAutofac, NotDerivedFrom>();
    

    编译时会失败。

    【讨论】:

    • 好的,谢谢您的回答。我想说编译时支持可以避免愚蠢的错误,例如,城堡和统一有这个机会。扩展是设计的拐杖,因此我对 autofac 中的“原生”感兴趣。
    • 使用 Autofac,您将在运行时提供此支持。在您致电builder.Build() 的那一刻验证配置。
    【解决方案2】:

    在 Steven 的回答的基础上,我更新了扩展方法以返回 IRegistrationBuilder 以使人们能够继续使用注册(设置范围等):

    public static class ContainerBuilderExtensions
    {
      public static IRegistrationBuilder<TImplementation, ConcreteReflectionActivatorData, SingleRegistrationStyle>
        RegisterType<TService, TImplementation>(this ContainerBuilder builder)
        where TImplementation : class, TService
        where TService : class
      {
        return builder.RegisterType<TImplementation>().As<TService>();
      }
    }
    

    示例用法:

    var builder = new ContainerBuilder();
    builder.RegisterType<IMyFactory, MyFactory>().SingleInstance();
    var container = builder.Build();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-05
      • 2011-09-04
      相关资源
      最近更新 更多