【问题标题】:Autofac SingleInstance not workingAutofac SingleInstance 不工作
【发布时间】:2012-05-10 23:10:03
【问题描述】:

我正在尝试让 Singleton 实例与 Autofac 一起使用。我有点用 Winforms 做一个 quasi-mvvm 类型的事情,只是一个实验,所以不要挂断电话。但我正在尝试让我的模型成为在命令中引用的单个实例(此处的 ICommand 不是 WPF 变体):

我有以下容器设置:

var cb = new ContainerBuilder();
cb.RegisterType<CalculateCommissionCommand>().As<ICommand<TradeEntry>>().SingleInstance();
cb.RegisterType<CalculationsModel>().As<ICalculationsModel>().SingleInstance();
cb.Register(c => new CalculationsView() { Model = c.Resolve<ICalculationsModel>() }).SingleInstance();
cb.Build();

现在,Command 将 ICalculationsModel 作为构造函数参数。但是,当我在传递给命令的模型中设置一个值时,该值不会出现在已经使用 CalculationsView 设置的模型中。尽管调用了“singleInstance”方法,但似乎命令和视图正在传递 CalculationsModel 的不同实例。我错过了什么吗?为什么会这样?

【问题讨论】:

  • 当我进行一些挖掘并放入一个带有本地自动递增实例化字段的静态计数器时,我看到实际上 autofac 每次都在创建新实例。传递给视图的实例 ID=1,传递给命令的实例 ID=2。只有当构造函数被调用两次时才会发生这种情况。是什么赋予了? Autofac 不会那么坏吧?
  • 在构造函数中下断点,看看是不是真的发生了两次
  • 是的。构造函数被调用了两次。
  • 从您的代码中不清楚您是如何存储/使用容器的,您是否有可能创建了多个容器?绝对不是 autofac 错了。
  • 实例化如下:ServiceLocator.SetLocatorProvider(() => new AutofacServiceLocator(ConfigureContainer()));我原始帖子中的上述代码包含在“配置容器”中,我从中返回 cb.Build()。然后我使用 ServiceLocator.Current.GetInstance<...>()。你认为是 serviceLocator 创建了容器的副本?嗯……我们来看看。

标签: singleton autofac


【解决方案1】:

我们今天遇到了类似的问题,这似乎是唯一提出这个问题的帖子,所以我想我会分享我们的经验,希望它可以帮助别人。最后它就在我们眼前,当然它们通常是最难解决的问题:-)。

在我们的场景中,我们是:

  1. 注册配置提供程序的特定实现
  2. 在程序集中自动注册某些类型。

类似的东西:

var cb = new ContainerBuilder();
cb.RegisterType<FileBasedConfigurationProvider>()
    .As<IConfigurationProvider>()
    .SingleInstance();

cb.RegisterAssemblyTypes(typeof(MailProvider).Assembly)
    .Where(t => !t.IsAbstract && t.Name.EndsWith("Provider"))
    .AsImplementedInterfaces(); 

愚蠢的是,我们没有想到/意识到FileBasedConfigurationProviderMailProvider 在同一个程序集中,所以第二次注册调用基本上覆盖了第一个;因此,SingleInstance“不起作用”。

希望对其他人有所帮助!

【讨论】:

  • +1,我今天犯了同样的错误。当您考虑它时,它是如此明显,但是当您陷入困境时,它确实不是最容易看到的。感谢您为我节省了一些调试时间:)
【解决方案2】:

从您的代码中不清楚您是如何存储/使用容器的。您可能已经创建了多个容器。

【讨论】:

    【解决方案3】:

    在我的情况下,问题是生成第二个实例的方法的参数被定义为类而不是接口 即

    SomeMethod(ClassName parameter)
    

    而不是

    SomeMethod(**I**ClassName parameter)
    

    明显的错误,但花了几分钟才看到。

    【讨论】:

      【解决方案4】:

      在我的例子中,我为一个类注册了两个不同的接口,声明每个都是单个实例。我假设该类只有一个实例……不,每个注册都有一个实例。

      例如

      builder.RegisterType<MyClass>().As<IMyFirstInterface>().SingleInstance();  // 1st instance 
      builder.RegisterType<MyClass>().As<IMySecondInterface>().SingleInstance(); // 2nd instance
      

      正确的做法是……

      builder
          .RegisterType<MyClass>()
          .As<IMyFirstInterface>()
          .As<IMySecondInterface>()
          .SingleInstance();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-13
        • 2018-05-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-29
        • 1970-01-01
        相关资源
        最近更新 更多