版本v2.4.5.724中的autofac注册问题

时间:2011-03-21 21:21:53

标签: autofac

我有以下注册

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];  
         });

2 个答案:

答案 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 IoChttp://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]; }; });