Проблема регистрации автозапуска в выпуске v2.4.5.724

У меня есть следующая регистрация

builder.Register<Func<Type, IRequestHandler>>(
          c => request => (IRequestHandler)c.Resolve(request));

В основном я пытаюсь зарегистрировать метод factory, который разрешает экземпляр IRequestHandler из заданного типа.

Это отлично работает до версии 2.4.3.700. Но теперь я получаю следующую ошибку.

Невозможно получить доступ к удаленному объекту. Имя объекта: "Эта операция разрешения уже завершена. когда регистрация компонентов с использованием лямбда, Параметр" c" IComponentContext лямбда не может быть сохранена. Вместо, либо снова разрешите IComponentContext от 'c' или разрешить Func < factory для создания последующих компоненты из. '.

UPDATE

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

 builder.Register<Func<Type,IRequestHandler>>(c =>  
         { 
           var handlers = c.Resolve<IIndex<Type,RequestHandler>>(); 
           return  request => handlers[request];  
         });

Ответы

Ответ 1

c в этом выражении является временным, поэтому этот код в то время, когда он был функциональным, нарушен. Autofac 2.4.5 обнаруживает эту проблему, в то время как более ранние версии молча игнорируют ее.

Чтобы устранить проблему, явно разрешите IComponentContext:

builder.Register<Func<Type, IRequestHandler>>(c => {
    var ctx = c.Resolve<IComponentContext>();
    return request => (IRequestHandler)ctx.Resolve(request));
});

Функциональность, которую вы эмулируете здесь, может быть лучше представлена ​​с использованием клавиш и индексов, например. см. Прерванная цепочка IoC или http://code.google.com/p/autofac/wiki/TypedNamedAndKeyedServices.

Ответ 2

У меня была аналогичная проблема с пользователем6130. Я хотел бы избежать использования IIndex в моей реализации класса и передать вместо этого в свой конструктор метод.

Итак, теперь у меня есть реализация моего сервиса со следующим конструктором:

public MvcMailer(Converter<string, MailerBase> mailerResolver)
{
     _resolver = mailerResolver;
}

код >

Я хотел использовать сервисы с ключами без прямой зависимости от пространства имен Autofac. Я получал ту же ошибку, пока не изменил конфигурацию как таковой.

1) Сканирование всех моих реализаций и индексации почтовой программы через имя класса (может быть улучшено)

builder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly())
       .Where(t => t.Name.EndsWith("Mailer")).Keyed<Mvc.Mailer.MailerBase>(t => t.Name.Replace("Mailer", "").ToLower());

код >

2) Зарегистрируйте преобразователь в конфигурации Autofac

builder.Register<System.Converter<string,Mvc.Mailer.MailerBase>>(c =>  {
    var all = c.Resolve<Autofac.Features.Indexed.IIndex<string,Mvc.Mailer.MailerBase>>();
         return delegate(string key)
         {
              return all[key];
         };
     });

код >

3) Зарегистрируйтесь, как и другие типы компонентов, и пусть Autofac обрабатывает инъекцию конвертера

builder.RegisterType<Mailers.MvcMailer>().As<Mailers.IMailer>();

код >