编译Autofac的时间支持

时间:2012-12-18 13:49:13

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

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

2 个答案:

答案 0 :(得分:4)

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

在编译时会失败。

答案 1 :(得分:0)

根据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();