C# 对Autofac的编译时支持

C# 对Autofac的编译时支持,c#,.net,castle-windsor,autofac,strong-typing,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<ITe

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

例如:

public interface ITestAutofac
{        
}

public class NotDerivedFrom
{        
}
对于温莎,我可以这样写-

var cont = new WindsorContainer();

cont.Register(Component
    .For<ITestAutofac>().ImplementedBy<NotDerivedFrom>());
var cont=新WindsorContainer();
连续寄存器(组件
.For().ImplementedBy());
它将在编译时失败。在这方面,Resharper可以很容易地提供帮助

对于Autofac,我可以这样写-

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

var form = container.Resolve<ICustomForm>();
builder.Register(c=>newnotderivedfrom()).As();
var form=container.Resolve();
它将在运行时失败

如何使用编译时检查在Autofac中注册类型?

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

如何使用编译时检查在Autofac中注册类型

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

公共静态无效寄存器(
这是一个集装箱建造商)
//注意这里的泛型类型约束
实施地点:类别、服务
where-TService:class
{
builder.Register().As();
}
这允许您按如下方式进行原始注册:

build.Register();
编译时将失败。

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

如何使用编译时检查在Autofac中注册类型

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

公共静态无效寄存器(
这是一个集装箱建造商)
//注意这里的泛型类型约束
实施地点:类别、服务
where-TService:class
{
builder.Register().As();
}
这允许您按如下方式进行原始注册:

build.Register();

编译时将失败。

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

公共静态类ContainerBuilderExtensions
{
公共静态IRegistrationBuilder
RegisterType(此ContainerBuilder生成器)
实施地点:类别、服务
where-TService:class
{
返回builder.RegisterType().As();
}
}
用法示例:

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

基于Steven的回答,我已更新了扩展方法,以返回
IRegistrationBuilder
,以便继续使用注册(设置范围等):

公共静态类ContainerBuilderExtensions
{
公共静态IRegistrationBuilder
RegisterType(此ContainerBuilder生成器)
实施地点:类别、服务
where-TService:class
{
返回builder.RegisterType().As();
}
}
用法示例:

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

好的,谢谢您的回答。我想说的是,编译时支持可以避免愚蠢的错误,例如,castle和unity有这个机会。扩展是设计中的一个支柱,因此我对autofac中的一些“本机”很感兴趣。使用autofac,您将在运行时获得这种支持。当您调用
builder.Build()
时,配置就会得到验证。好的,谢谢您的回答。我想说的是,编译时支持可以避免愚蠢的错误,例如,castle和unity有这个机会。扩展是设计中的一个支柱,因此我对autofac中的一些“本机”很感兴趣。使用autofac,您将在运行时获得这种支持。在调用
builder.Build()
时,将立即验证配置。