1

我们为我们的项目调查 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 中注册类型?

4

2 回答 2

4
builder.Register<NotDerivedFrom>().As<ITestAutofac>()

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

如何通过编译时检查在 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>();

这将在编译时失败。

于 2012-12-18T14:14:16.260 回答
0

基于史蒂文的回答,我更新了扩展方法以返回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();
于 2015-02-01T09:55:01.547 回答