我有以下注册
builder.Register<Func<Type, IRequestHandler>>(
c => request => (IRequestHandler)c.Resolve(request));
基本上我正在尝试注册一个解析来自给定类型的IRequestHandler实例的工厂方法。
这在版本2.4.3.700之前可以正常工作。但现在我收到了以下错误..
无法访问已处置的对象。 对象名称:'此解析操作已结束。什么时候 使用lambdas注册组件, IComponentContext'c'参数 lambda无法存储。代替, 或者再次解析IComponentContext 来自'c',或解析Func&lt;&gt;基于 工厂创建后续 来自。'。
的组件
更新
我试图限制autofac对解决方案中其他项目的曝光。尼克,谢谢你的提示,现在我的注册看起来像这样......
builder.Register<Func<Type,IRequestHandler>>(c =>
{
var handlers = c.Resolve<IIndex<Type,RequestHandler>>();
return request => handlers[request];
});
答案 0 :(得分: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。
答案 1 :(得分:0)
我遇到了与用户6130类似的问题。我想避免在我的类实现中使用IIndex
,而是将服务解析器传递给我的构造函数。
所以现在我使用以下构造函数实现了我的服务实现:
public MvcMailer(Converter<string, MailerBase> mailerResolver)
{
_resolver = mailerResolver;
}
我想在不直接依赖Autofac名称空间的情况下使用密钥服务。在我重新配置配置之前,我遇到了同样的错误。
1)通过类名扫描我的所有邮件程序实现和索引(可以改进)
public MvcMailer(Converter<string, MailerBase> mailerResolver)
{
_resolver = mailerResolver;
}
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.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly())
.Where(t => t.Name.EndsWith("Mailer")).Keyed<Mvc.Mailer.MailerBase>(t => t.Name.Replace("Mailer", "").ToLower());
3)像其他类型的组件一样注册,让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];
};
});
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];
};
});