2012-05-10 6 views
4

Я пытаюсь получить экземпляр Singleton, работающий с Autofac. Я вроде как делаю квази-mvvm типа с Winforms, просто эксперимент, поэтому не получится повесить на это. Но я пытаюсь вас есть моя модель будет один экземпляр со ссылкой на команду (ICommand здесь не разнообразие WPF):Autofac SingleInstance не работает

У меня есть следующие установки контейнера:

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

Теперь Команда принимает ICalculationsModel в качестве параметра конструктора. Однако, когда я устанавливаю значение в Модели, передаваемой команде, это значение не появляется в модели, которая уже была установлена ​​с помощью CalculationsView. Кажется, что команде и представлению передаются разные экземпляры CalculationsModel, несмотря на вызов метода singleInstance. Я что-то упускаю? Почему это происходит?

+0

Когда я немного разбираюсь и ставил статический счетчик с локальным автоматически увеличивающимся экземпляром поля, я вижу, что на самом деле autofac создает новые экземпляры каждый раз. Экземпляр, передаваемый в представление, имеет ID = 1, а экземпляр, переданный команде, равен ID = 2. Это может произойти только в том случае, если конструктор вызывался дважды. Что дает? Autofac не может быть сломанным? – Bitfiddler

+0

Положите точку останова в конструкторе и посмотрите, действительно ли это происходит дважды. – jlew

+1

Да. Конструктор вызывается дважды. – Bitfiddler

ответ

4

С вашего кода неясно, как вы храните/используете контейнер. Вероятно, вы создали несколько контейнеров.

7

Сегодня мы сталкиваемся с подобной проблемой, и это, кажется, единственное сообщение, на котором задан этот вопрос, поэтому я решил поделиться своим опытом с надеждой, что это поможет кому-то. В конце концов, это было что-то прямо перед нашими глазами, и, конечно, они, как правило, самые трудные проблемы для решения :-).

В нашем сценарии мы были:

  1. Регистрация специфической реализации поставщика конфигурации
  2. Auto-регистрирующего определенные типы в сборке.

Что-то вдоль этих линий:

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

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

Тупо, мы не думали об/понимать, что FileBasedConfigurationProvider был в той же сборке, что и MailProvider, поэтому второй регистрации вызова в основном переписал первый ; следовательно, SingleInstance «не работал».

Надеюсь, что это поможет кому-то еще!

+3

+1, я совершил ту же самую ошибку сегодня. Это так очевидно, когда вы думаете об этом, но на самом деле это не самая легкая вещь, чтобы видеть, когда вы в гуще. Спасибо, что спасли мне время отладки :) – wasatz

0

В моем случае проблема в том, что параметр метода генерации второй экземпляр был определен как класс вместо интерфейса т.е.

SomeMethod(ClassName parameter) 

вместо

SomeMethod(**I**ClassName parameter) 

Очевидная ошибка, но потребовалось несколько минут, чтобы увидеть это.

Смежные вопросы