2011-11-23 15 views
2

當我用從automapper映射autofac註冊的網絡類型,我得到這個錯誤:Autofac,ASP.NET MVC 3 HttpRequest的範圍和AutoMapper:不帶標籤匹配「的HttpRequest」範圍可見

No scope with a Tag matching 'httpRequest' is visible from the scope in which the instance was requested. This generally indicates that a component registered as per-HTTP request is being reqested by a SingleInstance() component (or a similar scenario.) Under the web integration always request dependencies from the DependencyResolver.Current or ILifetimeScopeProvider.RequestLifetime, never from the container itself.

當其他類型在其映射中起作用時被解析。 當網絡類型從控制器中解析出來後,它就可以工作。

爲什麼不能在我的映射中成功解析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解決任何服務。

回答

0

我想你應該在

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

這並不甚至編譯,但它改變到\t \t \t \t \t \t \t \t \t c.ConstructServicesUsing(DependencyResolver.Current.GetService);它編譯,但它仍然是同樣的問題。 – MatteS

2

@rene_r使用DependencyResolver.Current.Resolve代替container.Resolve以上是在正確的軌道上;適應他的回答:

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

仍然可能不會編譯,但應該讓你關閉。

的要求是調用DependencyResolver.Current將被推遲到服務請求(不保持當映射器被初始化由Current返回的值。)

+0

當我評論rene_r時,它仍然沒有解決問題。 – MatteS

+0

完全刪除了調用,因爲它使它沒有什麼不同,我不認爲它真的很重要,因爲在示例中沒有通過automapper解決服務。 – MatteS

+0

'var profiles = container.Resolve >();'不起作用 - 'MyProfile'依賴於每個請求類型的'HttpContext'('Func'不會改變這個)。 –

0

我最近也有類似的問題,它橫空出世在我的引導程序功能中是一個糟糕的設置。以下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>(); 
      }); 

引導後,它適用於我很好。