autofac:忽略组件注册

时间:2013-12-26 13:24:08

标签: c# autofac

以下类在构造函数上使用原语,因此我需要告诉AutoFac如何使用委托生成所述值:

public class BackgroundTaskScheduler : IStartable
{
    private readonly IJobRunner _jobRunner;
    private int _triggerMilliseconds;


    public BackgroundTaskScheduler(IJobRunner jobRunner, int triggerMilliseconds)
    {
        _jobRunner = jobRunner;
        _triggerTimespan = triggerMilliseconds;
    }
}


public static class AutoFac
{
    public static void Configure()
    {
        var builder = new ContainerBuilder();

        var triggerInterval =
                int.Parse(
                    ConfigurationManager.AppSettings["TaskScheduleTriggerMilliseconds"]);

        builder.Register(
            c => new BackgroundTaskScheduler(c.Resolve<IJobRunner>(), triggerInterval)).AsImplementedInterfaces().SingleInstance();

        builder.RegisterAssemblyTypes(typeof (RegistrationController).Assembly)
            .AsImplementedInterfaces()
            .AsSelf();

        IContainer container = builder.Build();

    }
}

但是,Autofac似乎忽略了我的注册,因为解析BackgroundTaskScheduler实例时抛出的异常证明了这一点:

可以使用可用的服务和参数调用“Delen.Server.Tasks.BackgroundTaskScheduler”类型中的'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'找到的构造函数: 无法解析构造函数'Void .ctor(Delen.Server.Tasks.IJobRunner,System.Int32)'的参数'System.Int32 triggerMilliseconds'。

我之前在这种情况下成功使用了IContainerBuilder.Register方法,但我不知道为什么它不能正常工作。

更新1

更改注册顺序没有任何区别。

更新2

这是获得与接受的答案相同结果的另一种方法:

builder.RegisterAssemblyTypes(typeof(IJobRunner).Assembly)
    .Except<BackgroundTaskScheduler>()
    .AsImplementedInterfaces()
    .AsSelf()

1 个答案:

答案 0 :(得分:1)

注册顺序 除了使用程序集扫描功能之外,如果您还希望手动注册类型,因为最终可能会干扰注册,那么注册顺序

在您的情况下,您正在注册BackgroundTaskScheduler 两次

  • 在调用builder.Register
  • 时使用正确的参数
  • 这次调用builder.RegisterAssemblyTypes时没有所需triggerInterval参数的第二种类型。

所以你结束了两次注册,其中一次注册不正确,因此在调用builder.Build时你会得到例外。

要解决此问题,您需要在RegisterAssemblyTypes调用中排除所有手动注册的类型:

builder.RegisterAssemblyTypes(typeof(AutofacRegistrationOrderTest).Assembly)
    .Where(t => t != typeof(BackgroundTaskScheduler))
    .AsImplementedInterfaces()
    .AsSelf();

builder.Register(
    c => new BackgroundTaskScheduler(c.Resolve<IJobRunner>(), triggerInterval))
    .AsImplementedInterfaces()
    .SingleInstance();