Egal, solange es sich um eine statische Klasse handelt. Es geht nur um Konventionen .
Unsere Konvention ist, dass jede "Schicht" (Web, Dienste, Daten) eine einzelne Datei hat, die aufgerufen wird AutoMapperXConfiguration.cs
, mit einer einzigen Methode, die aufgerufen wird Configure()
, wobei X
sich die Schicht befindet.
Die Configure()
Methode ruft dann private
Methoden für jeden Bereich auf.
Hier ist ein Beispiel für unsere Web-Tier-Konfiguration:
public static class AutoMapperWebConfiguration
{
public static void Configure()
{
ConfigureUserMapping();
ConfigurePostMapping();
}
private static void ConfigureUserMapping()
{
Mapper.CreateMap<User,UserViewModel>();
}
// ... etc
}
Wir erstellen eine Methode für jedes "Aggregat" (Benutzer, Beitrag), damit die Dinge gut getrennt sind.
Dann ist dein Global.asax
:
AutoMapperWebConfiguration.Configure();
AutoMapperServicesConfiguration.Configure();
AutoMapperDomainConfiguration.Configure();
// etc
Es ist wie eine "Schnittstelle von Wörtern" - kann es nicht erzwingen, aber Sie erwarten es, sodass Sie bei Bedarf Code (und Refactor) erstellen können.
BEARBEITEN:
Ich dachte nur, ich würde erwähnen, dass ich jetzt AutoMapper- Profile verwende . Das obige Beispiel lautet also:
public static class AutoMapperWebConfiguration
{
public static void Configure()
{
Mapper.Initialize(cfg =>
{
cfg.AddProfile(new UserProfile());
cfg.AddProfile(new PostProfile());
});
}
}
public class UserProfile : Profile
{
protected override void Configure()
{
Mapper.CreateMap<User,UserViewModel>();
}
}
Viel sauberer / robuster.
Mapper.Initialize
Überschreibt der Aufruf jeder Konfigurationsklasse die zuvor hinzugefügten Profile? Wenn ja, was sollte anstelle von Initialisieren verwendet werden?Mapper.CreateMap()
nun obselet.'Mapper.Map<TSource, TDestination>(TSource, TDestination)' is obsolete: 'The static API will be removed in version 5.0. Use a MapperConfiguration instance and store statically as needed. Use CreateMapper to create a mapper instance.'
. Wie würden Sie Ihr Beispiel aktualisieren, um es an die neuen Anforderungen anzupassen?Sie können es wirklich überall platzieren, solange Ihr Webprojekt auf die Assembly verweist, in der es sich befindet. In Ihrer Situation würde ich es in die Service-Schicht einfügen, da die Web-Schicht und die Service-Schicht darauf zugreifen können und später, wenn Sie dies wünschen Wenn Sie eine Konsolen-App ausführen oder ein Unit-Test-Projekt durchführen, ist die Zuordnungskonfiguration auch für diese Projekte verfügbar.
In Ihrer Global.asax rufen Sie dann die Methode auf, mit der alle Ihre Karten festgelegt werden. Siehe unten:
Datei AutoMapperBootStrapper.cs
Global.asax beim Anwendungsstart
Ruf einfach an
Jetzt werden einige Leute gegen diese Methode argumentieren und gegen einige SOLID-Prinzipien verstoßen, für die sie gültige Argumente haben. Hier sind sie zum Lesen.
Das Konfigurieren von Automapper in Bootstrapper verstößt gegen das Open-Closed-Prinzip?
quelle
Update: Der hier veröffentlichte Ansatz ist nicht mehr gültig, da
SelfProfiler
er ab AutoMapper v2 entfernt wurde.Ich würde einen ähnlichen Ansatz wie Thoai verfolgen. Aber ich würde die eingebaute
SelfProfiler<>
Klasse verwenden, um die Karten zu behandeln, und dann dieMapper.SelfConfigure
Funktion zum Initialisieren verwenden.Verwenden dieses Objekts als Quelle:
Und diese als Ziel:
Sie können diese Profile erstellen:
Erstellen Sie diese Klasse, um sie in Ihrer Anwendung zu initialisieren
Fügen Sie diese Zeile Ihrer Datei global.asax.cs hinzu:
AutoMapperConfiguration.Initialize()
Jetzt können Sie Ihre Mapping-Klassen dort platzieren, wo sie für Sie sinnvoll sind, und sich nicht um eine monolithische Mapping-Klasse kümmern.
quelle
Für diejenigen unter Ihnen, die sich an Folgendes halten:
Ich habe eine Kombination zwischen Profilen und der Nutzung meines ioc-Containers erstellt:
IoC-Konfiguration:
Konfigurationsbeispiel:
Anwendungsbeispiel:
Der Nachteil ist, dass Sie den Mapper über die IMappingEngine-Schnittstelle anstelle des statischen Mappers referenzieren müssen, aber das ist eine Konvention, mit der ich leben kann.
quelle
Alle oben genannten Lösungen bieten eine statische Methode zum Aufrufen (von app_start oder einem beliebigen Ort), mit der andere Methoden zum Konfigurieren von Teilen der Mapping-Konfiguration aufgerufen werden sollen. Wenn Sie jedoch eine modulare Anwendung haben, die Module jederzeit ein- und ausschalten können, funktionieren diese Lösungen nicht. Ich schlage vor, eine
WebActivator
Bibliothek zu verwenden, die einige Methoden registrieren kann, auf denen ausgeführt werden soll,app_pre_start
undapp_post_start
alle, wo:Sie können
WebActivator
über NuGet installieren .quelle
MyModule1
Erstellen Sie im Projekt (oder wie auch immer der Name Ihres Projekts lautet) einfach eine Klasse mit dem NamenInitMapInModule1
und fügen Sie den Code in die Datei ein. Machen Sie dasselbe für andere Module.Neben der besten Antwort ist die Verwendung von Autofac IoC liberary eine gute Möglichkeit , um eine gewisse Automatisierung hinzuzufügen. Damit definieren Sie einfach Ihre Profile unabhängig von Initiationen.
und Aufrufen dieser Zeile in
Application_Start
Methode:Der obige Code findet alle Profilunterklassen und initiiert sie automatisch.
quelle
Es ist für mich keine gute Praxis, die gesamte Zuordnungslogik an einem Ort zu platzieren. Weil die Mapping-Klasse extrem groß und sehr schwer zu pflegen ist.
Ich empfehle, das Mapping-Material zusammen mit der ViewModel-Klasse in derselben cs-Datei zusammenzustellen. Sie können gemäß dieser Konvention einfach zu der gewünschten Zuordnungsdefinition navigieren. Darüber hinaus können Sie beim Erstellen der Zuordnungsklasse schneller auf die ViewModel-Eigenschaften verweisen, da sie sich in derselben Datei befinden.
Ihre Ansichtsmodellklasse sieht also folgendermaßen aus:
quelle
Ab der neuen Version von AutoMapper mit der statischen Methode ist Mapper.Map () veraltet. Sie können also MapperConfiguration als statische Eigenschaft zu MvcApplication (Global.asax.cs) hinzufügen und damit eine Instanz von Mapper erstellen.
App_Start
Global.asax.cs
BaseController.cs
https://github.com/AutoMapper/AutoMapper/wiki/Migrating-from-static-API
quelle
Für diejenigen, die (verloren) sind mit:
So habe ich es geschafft, AutoMapper auf " neue Weise " zu integrieren. Auch ein großes Dankeschön an diese Antwort (und Frage)
1 - Im WebAPI-Projekt wurde ein Ordner mit dem Namen "ProfileMappers" erstellt. In diesem Ordner platziere ich alle meine Profilklassen, die meine Zuordnungen erstellen:
2 - In meinem App_Start habe ich einen SimpleInjectorApiInitializer, der meinen SimpleInjector-Container konfiguriert:
3 - Startup.cs
4 - Dann injizieren Sie in Ihren Controller wie gewohnt eine IMapper-Schnittstelle:
quelle
Für vb.net-Programmierer, die die neue Version (5.x) von AutoMapper verwenden.
Global.asax.vb:
AutoMapperConfiguration:
Profile:
Kartierung:
quelle
Protected Overrides Sub Configure()
ist also veraltet. Alles bleibt gleich, aber diese Zeile sollte sein:Public Sub New()