【问题标题】:Autofac, ASP.NET MVC 3 httpRequest scope and AutoMapper: No scope with a Tag matching 'httpRequest' is visibleAutofac、ASP.NET MVC 3 httpRequest 范围和 AutoMapper:没有标签匹配“httpRequest”的范围可见
【发布时间】:2011-11-23 13:39:19
【问题描述】:

当我从 automapper 映射中使用通过 autofac 注册的 web 类型时,我收到此错误:

从请求实例的范围中看不到带有与“httpRequest”匹配的标记的范围。这通常表明注册为 per-HTTP 请求的组件正在被 SingleInstance() 组件(或类似场景)请求。在 Web 集成下,始终从 DependencyResolver.Current 或 ILifetimeScopeProvider.RequestLifetime 请求依赖项,而不是从容器本身.

当在映射中解析另一种类型时,它会起作用。 当从控制器解析 Web 类型时,它会起作用。

为什么在我的映射中没有成功解析 web(或任何其他 httprequest 范围?)类型?

    protected void Application_Start()
    {
        var builder = new ContainerBuilder();
        builder.RegisterModule<AutofacWebTypesModule>();
        builder.RegisterControllers(Assembly.GetExecutingAssembly());
        builder.RegisterModelBinders(Assembly.GetExecutingAssembly());
        builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
            .AssignableTo<Profile>()
            .As<Profile>()
            ;
        builder.Register(c => Mapper.Engine)
            .As<IMappingEngine>();
        builder.RegisterType<AnotherType>()
            .As<IAnotherType>();
        var container = builder.Build();

        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

        var profiles = container.Resolve<IEnumerable<Profile>>();
        Mapper.Initialize(c => profiles.ToList().ForEach(c.AddProfile));

        AreaRegistration.RegisterAllAreas();

        RegisterGlobalFilters(GlobalFilters.Filters);
        RegisterRoutes(RouteTable.Routes);
    }

public class HomeController : Controller
{
    private readonly IMappingEngine _mapper;
    private readonly Func<HttpContextBase> _httpContext;

    public HomeController(IMappingEngine mapper, Func<HttpContextBase> httpContext)
    {
        _mapper = mapper;
        _httpContext = httpContext;
    }

    public ActionResult Index()
    {
        var test = _httpContext.Invoke();
        return View(_mapper.Map<Model, ViewModel>(new Model()));
    }

}

public class MyProfile : Profile
{
    private readonly Func<HttpContextBase> _httpContext;
    private readonly Func<IAnotherType> _anotherType;

    public MyProfile(Func<HttpContextBase> httpContext, Func<IAnotherType> anotherType)
    {
        _httpContext = httpContext;
        _anotherType = anotherType;
    }

    protected override void Configure()
    {
        CreateMap<Model, ViewModel>()
            .ForMember(d => d.Url, o => o.ResolveUsing(s =>
                                                    {
                                                        var test = _anotherType.Invoke().GetAValue();
                                                        return _httpContext.Invoke().Request.Url;
                                                    }))
            ;
    }
}

public interface IAnotherType
{
    string GetAValue();
}

public class AnotherType : IAnotherType
{
    public string GetAValue() { return "a value"; }
}

public class ViewModel
{
    public string Url { get; set; }
}

public class Model
{
}

编辑:很容易创建一个空的 MVC 项目,粘贴代码并自己尝试一下。

编辑:删除了 ConstructServicesUsing 调用,因为示例不需要它。示例中没有通过 AutoMapper 解析任何服务。

【问题讨论】:

    标签: asp.net-mvc-3 automapper autofac


    【解决方案1】:

    上面的@rene_r 是在正确的轨道上;调整他的答案:

    c.ConstructServicesUsing(t => DependencyResolver.Current.GetService(t))
    

    仍然可能无法编译,但应该让你接近。

    要求是对DependencyResolver.Current 的调用推迟到请求服务之前(不保留为初始化映射器时Current 返回的值。)

    【讨论】:

    • 完全删除了调用,因为它没有产生任何影响,而且我认为这并不重要,因为在示例中没有通过 automapper 解析任何服务。
    • var profiles = container.Resolve&lt;IEnumerable&lt;Profile&gt;&gt;(); 不起作用 - MyProfile 取决于 HttpContext,这是一个按请求类型(Func 不会改变这一点)。
    • 嗯,我在某处遵循了一个关于如何将依赖项传递给映射的示例,显然这在这种情况下不起作用。如果不是这样,你会如何建议我为我的映射提供依赖项?
    • 你在哪里可以得到这个工作?我也有类似的问题
    【解决方案2】:

    我认为你应该在

    中使用 DependencyResolver.Current.Resolve 而不是 container.Resolve
    Mapper.Initialize(c =>
                    {                               
                       c.ConstructServicesUsing(DependencyResolver.Current);
                       profiles.ToList().ForEach(c.AddProfile);
                     });
    

    【讨论】:

    • 这甚至没有编译,而是将其更改为 c.ConstructServicesUsing(DependencyResolver.Current.GetService);它编译,但它仍然是同样的问题。
    【解决方案3】:

    我最近遇到了类似的问题,结果证明这是我的引导程序函数中的错误设置。下面的 autofac 设置为我做了。

    builder.Register(c => new ConfigurationStore(new TypeMapFactory(), AutoMapper.Mappers.MapperRegistry.Mappers))
        .AsImplementedInterfaces()
        .SingleInstance();
    
    builder.Register(c => Mapper.Engine)
        .As<IMappingEngine>()
        .SingleInstance();
    
    builder.RegisterType<TypeMapFactory>()
        .As<ITypeMapFactory>()
        .SingleInstance();
    

    我不必在 Mapper.Initialize() 函数中指定解析器。刚刚调用

    Mapper.Initialize(x => 
                {
                    x.AddProfile<DomainToDTOMappingProfile>(); 
                });
    

    在引导之后,它对我来说很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-04
      • 1970-01-01
      • 2021-02-17
      • 2018-02-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多