2016-07-24 14 views
1

Ich kämpfe etwas über die Verwendung von Auto-Mapper in meinen Projektklassenbibliotheken (dlls). Siehe unten meine Struktur meiner Gesamtlösung.So initialisieren Sie AutoMapper-Profile in referenzierten Projekt-DLLs in ASP.Net webapp

Die WebApp wird gestartet und in Global.asax App Start wird die AutoMapper.Configure() -Methode aufgerufen, um die Zuordnungsprofile hinzuzufügen. Im Moment füge ich nur das Services.AutoMapperViewModelProfile hinzu. Aber ich muss irgendwie die Profile in jedem der WebStoreAdapter berücksichtigen (BigCommerce und Shopify im Beispiel unten). Ich hatte gehofft, keine Referenzen zu jedem WebStoreAdapter in WebApp hinzuzufügen, nur um die Profile während der AutoMapperConfig hinzufügen zu können. Wenn ich AutoMapper.Initialize in WebStoreFactory einen weiteren Aufruf hinzufüge, wird der in WebApp überschrieben.

Gibt es eine andere Möglichkeit, dass ich hier auf eine andere Weise fehlt oder völlig von der Basis entfernt bin?

WebApp 
    - AutoMapperConfig 
     - AddProfile Services.AutoMapperViewModelProfile 

    Services.dll   
     - AutoMapperViewModelProfile 

    Scheduler.dll (uses HangFire to execute cron jobs to get data from shop carts. Its UI is accessed via the WebApp) 

     WebStoreAdapter.dll 
      -WebStoreFactory 

       BigCommerceAdapter.dll 
        - AutoMapperBigCommerceDTOProfile 

       ShopifyAdapter.dll 
        - AutoMapperShopifyDTOProfile 

Initialisieren wie von Global.asax genannt:

public static class AutoMapperConfiguration 
{ 
    public static void Configure() 
    { 
     Mapper.Initialize(am => 
     { 
      am.AddProfile<AutoMapperViewModelProfile>(); 
     }); 
    }  
} 

Profil:

public class AutoMapperViewModelProfile : Profile 
{ 
    public override string ProfileName 
    { 
     get { return this.GetType().ToString(); } 
    } 

    protected override void Configure() 
    { 
     CreateMap<InventoryContainerHeader, InventoryContainerLabelPrintZPLViewModel>() 
       .ForMember(vm => vm.StatusDescription, opt => opt.MapFrom(entity => entity.InventoryContainerStatus.DisplayText)) 
       .ForMember(dest => dest.ContainerDetails, option => option.Ignore()) 
       ; 
     ... 
    } 
} 

Antwort

4

Eine Möglichkeit, dies zu tun, ist Reflexion zu verwenden, um alle Profile zu laden:

 var assembliesToScane = AppDomain.CurrentDomain.GetAssemblies(); 
     var allTypes = assembliesToScan.SelectMany(a => a.ExportedTypes).ToArray(); 

     var profiles = 
      allTypes 
       .Where(t => typeof(Profile).GetTypeInfo().IsAssignableFrom(t.GetTypeInfo())) 
       .Where(t => !t.GetTypeInfo().IsAbstract); 

     Mapper.Initialize(cfg => 
     { 
      foreach (var profile in profiles) 
      { 
       cfg.AddProfile(profile); 
      } 
     }); 

Sie verweisen nicht direkt ein beliebiges Profil, aber laden Sie einfach alle Profile aus der aktuellen AppDomain.