Autofac,ASP.NET MVC 3 httpRequest 作用域和自动映射器:没有具有与标记匹配'httpRequest'的作用域可见



当我使用autofac从automapper映射注册的web类型时,我得到这个错误:

在请求实例的作用域中没有标记匹配'httpRequest'的作用域可见。这通常表明,SingleInstance()组件(或类似的场景)正在请求按http请求注册的组件。在web集成中,总是从DependencyResolver请求依赖项。当前或ILifetimeScopeProvider。

当在映射中解析了另一个类型时,它可以工作。当一个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
{
}

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

EDIT:删除了ConstructServicesUsing调用,因为它不是示例所需要的。在本例中,没有服务通过AutoMapper解析。

@rene_r在正确的轨道上;改编他的回答:

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

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

需求是对DependencyResolver.Current的调用延迟到服务被请求(而不是作为初始化映射器时Current返回的值保留)

我认为你应该使用DependencyResolver.Current.Resolve而不是container。解析

Mapper.Initialize(c =>
                {                               
                   c.ConstructServicesUsing(DependencyResolver.Current);
                   profiles.ToList().ForEach(c.AddProfile);
                 });

我最近有一个类似的问题,它原来是一个糟糕的设置在我的bootstrapper函数。下面的自动设置为我完成了。

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

启动后,它对我来说工作得很好。

最新更新