Проблема регистрации автозапуска в выпуске 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>();
код >