خودکارسازی فرآیند نگاشت اشیاء در AutoMapper
نویسنده: سیروان عفیفی
تاریخ: ۱۳۹۴/۰۶/۰۱ ۱۷:۲۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
public class TestProfile1 : Profile
{
protected override void Configure()
{
// این تنظیم سراسری هست و به تمام خواص زمانی اعمال میشود
this.CreateMap<DateTime, string>().ConvertUsing(new DateTimeToPersianDateTimeConverter());
this.CreateMap<User, UserViewModel>();
// Other mappings
}
public override string ProfileName
{
get { return this.GetType().Name; }
}
} public interface IMapFrom<T>
{
}
public interface IHaveCustomMappings
{
void CreateMappings(IConfiguration configuration);
} public class PersonViewModel : IMapFrom<Person>
{
public string Name { get; set; }
public string LastName { get; set; }
} public class PersonViewModel : IHaveCustomMapping
{
public string Name { get; set; }
// دیگر پراپرتیها
public void CreateMappings(IConfiguration configuration)
{
configuration.CreateMap<ApplicationUser, PersonViewModel>()
.ForMember(m => m.Name, opt =>
opt.MapFrom(u => u.ApplicationUser.UserName));
// دیگر نگاشتها
}
} public void Execute()
{
var types = Assembly.GetExecutingAssembly().GetExportedTypes();
LoadStandardMappings(types);
LoadCustomMappings(types);
} private static void LoadStandardMappings(IEnumerable <Type> types)
{
var maps = (from t in types
from i in t.GetInterfaces()
where i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapFrom< >) && !t.IsAbstract && !t.IsInterface
select new {
Source = i.GetGenericArguments()[0],
Destination = t
}).ToArray();
foreach(var map in maps)
{
Mapper.CreateMap(map.Source, map.Destination);
}
} private static void LoadCustomMappings(IEnumerable <Type> types)
{
var maps = (from t in types
from i in t.GetInterfaces()
where typeof(IHaveCustomMappings).IsAssignableFrom(t) && !t.IsAbstract && !t.IsInterface
select(IHaveCustomMappings) Activator.CreateInstance(t)).ToArray();
foreach(var map in maps)
{
map.CreateMappings(Mapper.Configuration);
}
} _contacts.ProjectTo<ContactViewModel>(_mapper.ConfigurationProvider).ToList();
Mapper not initialized. Call Initialize with appropriate configuration
_mapper.Map<ContactViewModel>(contact);
cfg.CreateMap<Contact, ContactViewModel>();
Mapper.CreateMap(map.Source, map.Destination);
Mapper.CreateMap<map.Source, map.Destination>();
For<IMapper>().Use(ctx => ctx.GetInstance<MapperConfiguration>().CreateMapper(ctx.GetInstance));
public class AutomapperRegistry : Registry
{
public AutomapperRegistry()
{
For<MapperConfiguration>().Use("", ctx =>
{
var config = new MapperConfiguration(cfg =>
{
AutomapperConfig.setup(cfg, ctx);
});
config.AssertConfigurationIsValid();
return config;
}).Singleton();
For<IMapper>()
.HttpContextScoped()
.Use(ctx =>
ctx.GetInstance<MapperConfiguration>().CreateMapper(ctx.GetInstance));
}
} public static class AutomapperConfig
{
public static void setup(IMapperConfigurationExpression mappconfig, IContext ctx)
{
configureAutoMapper(mappconfig, ctx);
}
private static void configureAutoMapper(IMapperConfigurationExpression mappconfig, IContext ctx)
{
var profiles = ctx.GetAllInstances<AutoMapper.Profile>().ToList();
foreach (var profile in profiles)
{
mappconfig.AddProfile(profile);
}
var types = Assembly.GetExecutingAssembly().GetExportedTypes();
LoadStandardMappings(types, mappconfig);
LoadCustomMappings(types, mappconfig);
}
private static void LoadStandardMappings(IEnumerable<Type> types, IMapperConfigurationExpression mapper)
{
var maps = (from t in types
from i in t.GetInterfaces()
where i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMapFrom<>) && !t.IsAbstract && !t.IsInterface
select new
{
Source = i.GetGenericArguments()[0],
Destination = t
}).ToArray();
foreach (var map in maps)
{
mapper.CreateMap(map.Source, map.Destination);
}
}
private static void LoadCustomMappings(IEnumerable<Type> types, IMapperConfigurationExpression mapper)
{
var maps = (from t in types
from i in t.GetInterfaces()
where typeof(IHaveCustomMappings).IsAssignableFrom(t) && !t.IsAbstract && !t.IsInterface
select (IHaveCustomMappings)Activator.CreateInstance(t)).ToArray();
foreach (var map in maps)
{
map.CreateMappings(mapper);
}
}
} //var types = Assembly.GetExecutingAssembly().GetExportedTypes(); var types = typeof(PersonViewModel).Assembly.GetExportedTypes();
cfg.Scan(scan =>
{
scan.AssemblyContainingType<SomeType1>();
scan.AssemblyContainingType<SomeType2>();
}); public class SupplierViewModel
{
public string name { get; set; }
public AddressViewModel AddressViewModel { get; set; }=new AddressViewModel(); }
public class AddressViewModel
{
public string phone_mobile { get; set; }
public string address1 { get; set; }
}
public class Supplier
{
public int Id { get; set; }
public string name { get; set; }
public virtual Address Address { get; set; }
}
CreateMap<Supplier, SupplierViewModel>().IgnoreAllUnmapped() });
CreateMap<Address, AddressViewModel>()
var viewModel =
await _suppliers.AsNoTracking()
.ProjectTo<SupplierViewModel>(parameters:null,configuration: _mappingEngine.ConfigurationProvider)
.FirstOrDefaultAsync(a => a.Id == id); var config = new MapperConfiguration(cfg =>
{
cfg.CreateMissingTypeMaps = true; LoadStandardMappings(); LoadCustomMappings();
private void addAllIHaveCustomMappings(IContext ctx, IMapperConfigurationExpression cfg)
{
var profiles = ctx.GetAllInstances<IHaveCustomMappings>().ToList();
foreach (var profile in profiles)
{
profile.CreateMappings(cfg);
}
} در ضمن ویومدلها در لایه سرویس و پروژه دیگری میباشد.
scan.AssemblyContainingType<SomeTypeInThatAssembly>();
public class MyViewModel : IHaveCustomMappings
{
public int SchedulerId { get; set; }
public bool IsApplied { get; set; }
public int Qty { get; set; }
public void CreateMappings(IMapperConfigurationExpression configuration)
{
configuration.CreateMap<DomainModels.Models.Scheduler, MyViewModel>()
.ForMember(dest => dest.SchedulerId, opt => opt.MapFrom(src => src.Id));
}
} Unmapped members were found. Review the types and members below. Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type For no matching constructor, add a no-arg ctor, add optional arguments, or map all of the constructor parameters