我必须使用Autofac显式绑定普通类吗?

Dou*_*oug 7 c# autofac

我似乎在我的代码中做了这么多:

public class ActionsModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            base.Load(builder);
            builder.Register(c => LogManager.GetCurrentClassLogger()).As<ILog>().InstancePerDependency();

            // Autofac doesn't seem to be able to inject things without explicit binding 
            builder.RegisterType<ComboActions>().As<ComboActions>().InstancePerHttpRequest();
            builder.RegisterType<AppActions>().As<AppActions>().InstancePerHttpRequest();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

'actions'类是一个类,我需要将其注入到我的控制器中,并具有各种其他子依赖项.

似乎有点垃圾.为什么autofac无法解析该类是否具有已满足依赖关系的构造函数并自动生成实例?

我的意思是,如果A类需要注入B类而B类需要C,D,E等等,我想你不想走遍整个依赖链,看看你是否可以在运行时创建一个类....但是如果A类直接依赖于明确约束的C和D,那肯定是一个微不足道的案例?

我错过了什么吗?似乎没有看到任何相关的文档......

Kal*_*son 26

您不必注册每种类型.Autofac提供AnyConcreteTypeNotAlreadyRegisteredSource,如果您尚未提供注册,它将自动获取具体类型.

例如:

var builder = new ContainerBuilder();
builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource());
var container = builder.Build();
...
var myConcreteType = container.Resolve<MyConcreteType>();
Run Code Online (Sandbox Code Playgroud)

源允许更复杂的事情,例如为接口自动注入模拟对象和基于抽象类的依赖项.

  • 这是惊人的,特别是因为你可以做类似`builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource(x => x.Name.Contains("ViewModel")));; (3认同)

Jim*_*lla 2

AFAIK,Autofac 要求在容器中注册每种需要的类型,但这并不意味着您必须单独注册每一种类型。我几乎 99% 的注册都是通过将此属性添加到类型中来处理的:

[AttributeUsage(AttributeTargets.Class)]
public class AutoRegisterAttribute : Attribute { }
Run Code Online (Sandbox Code Playgroud)

例如,你有

[AutoRegister]
class ComboActions
{
Run Code Online (Sandbox Code Playgroud)

然后我用这个注册它们:

public class AutoScanModule : Module
{
    private readonly Assembly[] _assembliesToScan;

    public AutoScanModule(params Assembly[] assembliesToScan)
    {
        _assembliesToScan = assembliesToScan;
    }

    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterAssemblyTypes(_assembliesToScan)
            .Where(t => t.GetCustomAttributes(typeof (AutoRegisterAttribute), false).Any())
            .AsSelf()
            .AsImplementedInterfaces()
            .InstancePerLifetimeScope();
    }
}
Run Code Online (Sandbox Code Playgroud)

就像我说的,这涵盖了我的大部分注册,然后我通常只需要担心诸如第 3 方类型、开放泛型和装饰器之类的事情。

编辑:查看Kaleb 的回复,证明我错了。我从来不知道的很酷的功能!