проблема с автоматической регистрацией в выпуске v2.4.5.724 - PullRequest
13 голосов
/ 22 марта 2011

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

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

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

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

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

UPDATE

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

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

Ответы [ 2 ]

20 голосов
/ 22 марта 2011

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.

0 голосов
/ 11 января 2013

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

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

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

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

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

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

2) Зарегистрировать конвертер в конфигурации Autofac

</p> <pre><code>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 обрабатывает преобразователь впрыска

</p> <pre><code>builder.RegisterType<Mailers.MvcMailer>().As<Mailers.IMailer>();

...