Dove posizionare la registrazione della mappa AutoMapper nella dll di riferimento

Questo è il mio primo progetto AutoMapper e potrebbe essere ovvio per alcuni, ma i tutorial e gli esempi non fanno clic con me. Sto cercando di capire dove e in una certa misura come registrare (penso di volere i profili) le mie mappe per l’uso. Ci sono molti esempi MVC che dicono di usare l’asax globale e questo ha senso, ma qual è l’equivalente in un progetto di libreria?

Nella mia sandbox ho un’app winform e una libreria principale. L’app winform chiama i metodi resi disponibili dalla libreria ed è uno di questi metodi di libreria che fa uso di automapper.

Quindi per qualche sfondo ecco la mia mappa: (e per essere chiari, la mapping è nel progetto della libreria di base SAME)

public class Raw_Full_Map { public Raw_Full_Map() { Mapper.CreateMap<IEnumerable, FullData>() .ForMember(d => d.Acres, m => m.ResolveUsing(new RawLeadDataNameResolver("Acres"))); //this is clearly just a snip to show it's a basic map } } 

Questo è il metodo della libreria di base che viene chiamato: (si noti che è un static … il che significa che non avrò un costruttore … se questo è il problema, devo capire che AutoMapper non può essere utilizzato da classi helper statiche … non ha senso …. quindi probabilmente non sto facendo bene.

 public static class RawDataProcessing { public static FullData HTMLDataScrape(string htmlScrape) { HtmlDocument doc = new HtmlDocument(); doc.LoadHtml(htmlScrape); var list = Recurse(doc.DocumentNode); //HTML agility stuff that turns my html doc into a List object return Mapper.Map(list); } 

Il mio test harness lo chiama così:

 var _data = RawDataProcessing.HTMLDataScrape(rawHTML); 

Questo ovviamente errori perché la mappa non è “registrata”.

Se faccio questo nel cablaggio di prova:

 var x = new RawData_FullData(); var _data = RawDataProcessing.HTMLDataScrape(rawHTML); 

Quindi tutto funziona come se la mia mappa venisse registrata anche se penso in un modo davvero falso … ma funziona.

Quindi la domanda è: come posso registrare la mia mapping nel progetto della libreria di base … in modo che QUALSIASI metodo possa usarlo … non c’è davvero un global.asax equivalente in una DLL?

Grazie per avermi aiutato a colbind i pezzi mancanti.

Inseriscilo nel costruttore statico della sorgente o del tipo di destinazione della mapping.

 public class FullData { static FullData() { Mapper.CreateMap, FullData>() .ForMember(d => d.Acres, m => m.ResolveUsing(new RawLeadDataNameResolver("Acres"))); } } 

Il costruttore statico verrà chiamato automaticamente la prima volta che si tenta di utilizzare il tipo FullData per qualsiasi cosa (ad esempio una mapping).

È ansible utilizzare PreApplicationStartMethod per qualsiasi class e il suo metodo nella libreria di classi a cui verrà fatto riferimento dal progetto di avvio se si desidera richiamarlo automaticamente all’avvio. E poi puoi registrare tutti i tuoi mapping in quel metodo. A proposito, suggerisco di usare AddProfile per registrare tutti i mapping.

 [assembly: PreApplicationStartMethod(typeof(MyClassLibrary.Startup), "Start")] namespace MyClassLibrary { public class Startup { // Automatically will work on startup public static void Start() { Mapper.Initialize(cfg => { Assembly.GetExecutingAssembly().FindAllDerivedTypes().ForEach(match => { cfg.AddProfile(Activator.CreateInstance(match) as Profile); }); }); } } } 

Hai solo bisogno di creare nuove classi derivate dalla class Profile e quindi sovrascrivere il suo metodo Configure() :

 ... public class FooMapperProfile:Profile { protected override void Configure() { Mapper.CreateMap() .ForMember(... ... // so on } } public class AnotherFooMapperProfile:Profile { protected override void Configure() { Mapper.CreateMap() .ForMember(... ... // so on; } } ... // and so on 

Ulteriori informazioni: Se hai visto ho inizializzato tutti i mapping con quel codice:

 Mapper.Initialize(cfg => { Assembly.GetExecutingAssembly().FindAllDerivedTypes().ForEach(match => { cfg.AddProfile(Activator.CreateInstance(match) as Profile); }); }); 

Troverà automaticamente tutti i tipi derivati ​​da Profile e aggiungerà tutti i profili dopo aver creato le loro nuove istanze.

Update1:

Come commentato da PreApplicationStartMethod Chamberlain , PreApplicationStartMethod funziona solo per le applicazioni ASP.NET. Questo non funzionerebbe con un’app desktop. Se stai lavorando con Wpf , puoi utilizzare il metodo Application.OnStartup . Oppure chiama semplicemente Start.Startup (); in evento di carico.

Update2:
FindAllDerivedTypes estensione FindAllDerivedTypes :

  public static class AssemblyExtensions { public static List FindAllDerivedTypes(this Assembly assembly) { var derivedType = typeof(T); return assembly.GetTypes() .Where(t => t != derivedType && derivedType.IsAssignableFrom(t)) .ToList(); } }