2013-07-21 6 views
3

내 autopmapper typeconverters에 aufotac을 주입하는 데 문제가 있습니다. 필자는 다른 방법을 시도했지만 현재 아래의 코드를 사용하여 붙어 있습니다. 솔루션을 찾는 데 가장 가까운 것은 아래 코드입니다 (http://thoai-nguyen.blogspot.se/2011/10/autofac-automapper-custom-converter-di.html에서 작은 비트를 빌려 왔습니다). 그의 표본은 1 : 1로 작동하지만 보이지 않는 것을 찾을 수 없었다. 평소와 같이 적절한 비트를 추출했는지 알려주세요. Automapper 및 Autofac typeconverter - 기본 생성자가 없습니다

내 autofac 부트 스트 래퍼 :

public class AutoFacInitializer 
    { 
     public static void Initialize() 
     { 
      //Mvc 
      var MvcContainer = BuildMvcContainer(); 
      DependencyResolver.SetResolver(new AutofacDependencyResolver(MvcContainer)); 

      //Web API 
      var ApiContainer = BuildApiContainer(); 
      var ApiResolver = new AutofacWebApiDependencyResolver(ApiContainer); 
      GlobalConfiguration.Configuration.DependencyResolver = ApiResolver; 
     } 

     private static IContainer BuildApiContainer() 
     { 
      var builder = new ContainerBuilder(); 
      var assembly = Assembly.GetExecutingAssembly(); 
      builder.RegisterApiControllers(assembly); 
      return BuildSharedDependencies(builder, assembly); 
     } 

     private static IContainer BuildMvcContainer() 
     { 
      var builder = new ContainerBuilder(); 
      var assembly = typeof (MvcApplication).Assembly; 
      builder.RegisterControllers(assembly); 
      builder.RegisterFilterProvider(); 
      return BuildSharedDependencies(builder, assembly); 
     } 

     private static IContainer BuildSharedDependencies(ContainerBuilder builder, Assembly assembly) 
     { 
      //----Build and return container---- 
      IContainer container = null; 

      //Automapper 
      builder.RegisterAssemblyTypes(assembly).AsClosedTypesOf(typeof(ITypeConverter<,>)).AsSelf(); 
      AutoMapperInitializer.Initialize(container); 
      builder.RegisterAssemblyTypes(assembly).Where(t => typeof(IStartable).IsAssignableFrom(t)).As<IStartable>().SingleInstance(); 

      //Modules 
      builder.RegisterModule(new AutofacWebTypesModule()); 
      builder.RegisterModule(new NLogLoggerAutofacModule()); 

      //Automapper dependencies 
      builder.Register(x => Mapper.Engine).As<IMappingEngine>().SingleInstance(); 

      //Services, repos etc 
      builder.RegisterGeneric(typeof(SqlRepository<>)).As(typeof(IRepository<>)).InstancePerDependency(); 

      container = builder.Build(); 
      return container; 
     } 
    } 

내 오토 부트 스트 래퍼/초기화 :

namespace Supportweb.Web.App_Start 
{ 
    public class AutoMapperInitializer 
    { 
     public static void Initialize(IContainer container) 
     { 
      Mapper.Initialize(map => 
      { 
       map.CreateMap<long?, EntityToConvertTo>().ConvertUsing<LongToEntity<NavigationFolder>>(); 

       map.ConstructServicesUsing(t => container.Resolve(t)); 
      }); 
      Mapper.AssertConfigurationIsValid(); 
     } 
    } 
} 

작업려고 메신저 TypeConverter가 : 모든 매핑 컨버터를 제외하고

public class LongToEntity<T> : ITypeConverter<long?, T> 
    { 
     private readonly IRepository<T> _repo; 

     public LongToEntity(IRepository<T> repo) 
     { 
      _repo = repo; 
     } 

     public T Convert(ResolutionContext context) 
     { 
      long id = 0; 
      if (context.SourceValue != null) 
       id = (long)context.SourceValue; 
      return _repo.Get(id); 
     } 
    } 

을 잘 작동합니다. 이 오류는 ioc 참조가 부족하지만 imive는 시도했지만 ITypeConverter <,> 및 LongToEntity <> 및 그 변형이 도움이되지 않는다는 것을 나타냅니다.

답변

5

당신은 현재의 코드 세 가지 문제가 있습니다

링크 된 문서에서 설명한대로 모든 매핑을 등록 전에 ConstructServicesUsing 를 호출 할 필요가
  1. :

    까다로운 것은 우리가 필요하다 매퍼 클래스를 등록하기 전에 해당 메소드를 호출해야합니다.

    그래서 올바른 Mapper.Initialize이있는 follwing을 : 당신의 LongToEntity<T> 오픈 제네릭

    Mapper.Initialize(map => 
         { 
          map.ConstructServicesUsing(t => container.Resolve(t)); 
    
          map.CreateMap<long?, EntityToConvertTo>() 
           .ConvertUsing<LongToEntity<NavigationFolder>>(); 
         }); 
    
  2. 때문에 당신이 AsClosedTypesOf을 사용할 수 있지만 등록도 여기에 RegisterGeneric를 사용해야합니다 :

    따라서 ITypeConverter<,> 등록을 다음에서 변경하십시오.

    builder.RegisterAssemblyTypes(assembly) 
         .AsClosedTypesOf(typeof(ITypeConverter<,>)).AsSelf(); 
    
    별도의 방법으로 Automapper 초기화를 이동했기 때문에 당신이 기사에서 Clojure의 트릭을 사용할 수 없습니다 AutoMapperInitializer.Initialize 당신은 당신이 후 를 호출 할 필요가 있으므로,

    builder.RegisterGeneric(typeof(LongToEntity<>)).AsSelf(); 
    
  3. :

    RegisterGeneric 방법을 사용하려면 입력 용

    container = builder.Build(); 
    AutoMapperInitializer.Initialize(container); 
    return container; 
    
들으
+0

: 용기를 만들었다. 나는 이니셜 라이저와 컨스트럭션 서비스를 일찍 옮겼지만 어떤 차이점도 발견하지 못했다. 완전히 registergeneric 부분을 간과했지만. 조언에 따라 Ajdusted를 실행하면 "AutofacWebRequest와 일치하는 태그가있는 범위가 인스턴스가 요청 된 범위에서 보이지 않습니다."라는 오류 메시지가 나타납니다. – Baserz

+0

그렇다면 Autofac 해상도가 작동하기 시작하면 완전히 관련없는 문제가 발생합니다.다른 질문으로이 질문을해야하지만 먼저이 질문을 참고하십시오 : http://stackoverflow.com/questions/12802073/scope-error-when-using-autofac-with-signalr 귀하의 문제와 유사합니다. – nemesv

+0

전체 등록을 보지 않고서는 문제의 원인을 알기가 어렵습니다. 아마도'LongToEntity'에서'InstepotPerLifetimeScope'에 등록 된 어떤 타입을 (아마'IRepository' 구현에서) 참조하고 있습니다 ... – nemesv

관련 문제