2011-03-21 4 views
13

У меня есть после регистрацииautofac вопрос о регистрации в релизе v2.4.5.724

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

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

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

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

UPDATE

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

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

ответ

20

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

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

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

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

0

У меня была аналогичная проблема с пользователем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>(); 

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