Nie ma znaczenia, o ile jest to klasa statyczna. Chodzi o konwencję .
Naszą konwencją jest to, że każda „warstwa” (sieć, usługi, dane) ma jeden plik o nazwie AutoMapperXConfiguration.cs
, z jedną metodą o nazwie Configure()
, gdzie X
jest warstwa.
Następnie Configure()
metoda wywołuje private
metody dla każdego obszaru.
Oto przykład naszej konfiguracji warstwy internetowej:
public static class AutoMapperWebConfiguration
{
public static void Configure()
{
ConfigureUserMapping();
ConfigurePostMapping();
}
private static void ConfigureUserMapping()
{
Mapper.CreateMap<User,UserViewModel>();
}
// ... etc
}
Tworzymy metodę dla każdego „agregatu” (użytkownika, posta), więc wszystko jest ładnie rozdzielone.
Następnie twój Global.asax
:
AutoMapperWebConfiguration.Configure();
AutoMapperServicesConfiguration.Configure();
AutoMapperDomainConfiguration.Configure();
// etc
To trochę jak „interfejs słów” - nie można go narzucić, ale można się tego spodziewać, więc w razie potrzeby można kodować (i refaktoryzować).
EDYTOWAĆ:
Pomyślałem, że wspomnę, że teraz używam profili AutoMapper , więc powyższy przykład wygląda następująco :
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>();
}
}
Dużo czystszy / bardziej wytrzymały.
Mapper.Initialize
w każdej klasie konfiguracji zastępuje poprzednie dodane profile? Jeśli tak, to czego należy użyć zamiast Inicjalizacji?Mapper.CreateMap()
jest teraz obselete.'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.'
. Jak zaktualizowałbyś swój przykład, aby spełniał nowe wymagania?Możesz naprawdę umieścić go w dowolnym miejscu, o ile projekt sieciowy odwołuje się do zestawu, w którym się znajduje. W twojej sytuacji umieściłbym go w warstwie usługi, ponieważ będzie on dostępny dla warstwy sieci i warstwy usługi, a później, jeśli zdecydujesz się zrobić aplikację na konsolę lub wykonujesz projekt testu jednostkowego, konfiguracja mapowania będzie również dostępna z tych projektów.
Następnie w Global.asax wywołujesz metodę, która ustawia wszystkie twoje mapy. Patrz poniżej:
Plik AutoMapperBootStrapper.cs
Global.asax przy starcie aplikacji
Zadzwoń
Teraz niektórzy ludzie będą argumentować przeciwko tej metodzie naruszającej niektóre zasady SOLID, które mają uzasadnione argumenty. Tutaj są do czytania.
Konfigurowanie Automappera w Bootstrapperie narusza zasadę Open-Closed?
źródło
Aktualizacja: Podane tutaj podejście nie jest już aktualne jako
SelfProfiler
zostało usunięte z wersji AutoMapper v2.Przyjąłbym podobne podejście jak Thoai. Ale użyłbym wbudowanej
SelfProfiler<>
klasy do obsługi map, a następnie użyłemMapper.SelfConfigure
funkcji do zainicjowania.Używając tego obiektu jako źródła:
A te jako cel:
Możesz utworzyć te profile:
Aby zainicjować w aplikacji, utwórz tę klasę
Dodaj tę linię do pliku global.asax.cs:
AutoMapperConfiguration.Initialize()
Teraz możesz umieścić swoje klasy mapowania tam, gdzie mają dla ciebie sens, i nie martwić się o jedną monolityczną klasę mapowania.
źródło
Dla tych z was, którzy przestrzegają następujących zasad:
Zrobiłem kombinację między profilami i wykorzystując mój kontener ioc:
Konfiguracja IoC:
Przykład konfiguracji:
Przykład użycia:
Kompromis polega na tym, że musisz odwoływać się do Mappera za pomocą interfejsu IMappingEngine zamiast statycznego Mappera, ale jest to konwencja, z którą mogę żyć.
źródło
Wszystkie powyższe rozwiązania zapewniają statyczną metodę wywoływania (z app_start lub dowolnego innego miejsca), która powinna wywoływać inne metody konfigurowania części konfiguracji mapowania. Ale jeśli masz aplikację modułową, moduły te mogą się w dowolnym momencie podłączać i wyłączać z aplikacji, te rozwiązania nie działają. Sugeruję użycie
WebActivator
biblioteki, która może zarejestrować niektóre metody do uruchomieniaapp_pre_start
iapp_post_start
dowolne gdzie:Możesz zainstalować
WebActivator
za pomocą NuGet.źródło
MyModule1
projekcie (lub jakiejkolwiek nazwie jest Twój projekt) po prostu stwórz klasę o nazwieInitMapInModule1
i umieść kod w pliku; w przypadku innych modułów zrób to samo.Oprócz najlepszej odpowiedzi, dobrym sposobem jest użycie oprogramowania Autofac IoC liberary w celu dodania automatyzacji. Mając to ty właśnie zdefiniowanie profili niezależnie od inicjacji.
i wywołanie tej linii w
Application_Start
metodzie:Powyższy kod wyszukuje wszystkie podklasy Profile i inicjuje je automatycznie.
źródło
Umieszczenie całej logiki mapowania w 1 lokalizacji nie jest dla mnie dobrą praktyką. Ponieważ klasa mapowania będzie bardzo duża i bardzo trudna w utrzymaniu.
Polecam umieszczenie mapowania razem z klasą ViewModel w tym samym pliku cs. Możesz łatwo przejść do definicji mapowania, która ma być zgodna z tą konwencją. Ponadto podczas tworzenia klasy odwzorowania można szybciej odwoływać się do właściwości ViewModel, ponieważ znajdują się one w tym samym pliku.
Twoja klasa modelu widoku będzie wyglądać następująco:
źródło
Od nowej wersji AutoMapper przy użyciu metody statycznej Mapper.Map () jest przestarzały. Możesz więc dodać MapperConfiguration jako właściwość statyczną do MvcApplication (Global.asax.cs) i użyć jej do utworzenia instancji Mappera.
App_Start
Global.asax.cs
BaseController.cs
https://github.com/AutoMapper/AutoMapper/wiki/Migrating-from-static-API
źródło
Dla tych, którzy są (zagubieni) używając:
Oto jak udało mi się zintegrować AutoMapper w „ nowy sposób ”. Również Ogromne dzięki tej odpowiedzi (i pytanie)
1 - Utworzono folder w projekcie WebAPI o nazwie „ProfileMappers”. W tym folderze umieszczam wszystkie moje klasy profili, które tworzą moje mapowania:
2 - W moim App_Start mam SimpleInjectorApiInitializer, który konfiguruje mój kontener SimpleInjector:
3 - Startup.cs
4 - Następnie w swoim kontrolerze po prostu wstrzyknij jak zwykle interfejs IMapper:
źródło
Dla programistów vb.net korzystających z nowej wersji AutoMapper (5.x).
Global.asax.vb:
Konfiguracja AutoMapper:
Profile:
Mapowanie:
źródło
Protected Overrides Sub Configure()
jest przestarzałe. Wszystko pozostaje takie samo, ale ta linijka powinna brzmieć:Public Sub New()