AutoMapper的配置方法

AutoMapper与ASP.NET MVC结合,一般会在Controller的Action中使用AutoMapper把前台传递过来的Presentation Model转换成相应的业务逻辑上的Entity Model.如果在Action中写AutoMapper.CreateMap<T1,T2>,这些代码未免与业务逻辑无多大关系,所以不应该写在Action中。我们可以利用ASP.NET MVC中的Filter这个特点,以过滤器的方式在执行Action中AutoMapper的转换前就完成配置。


首先,要定义一个MyProfile, 继承自AutoMapper的Profile类,并且重写Configure()方法,在这个方法中进行配置。
public class OrderDomainMvcProfile : Profile
    {
        public override string ProfileName
        {
            get { return "OrderDomainMvcProfile"; }
        }

        protected override void Configure()
        {
            // Map……
	    Mapper.CreateMap<T1, T2>().ForMember(……);
	}
}

然后再Filter中进行加载

[AttributeUsageAttribute(AttributeTargets.Class |AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
public class AutoMapperConfigurationActionFilterAttribute : FilterAttribute
{
    public AutoMapperConfigurationActionFilterAttribute(Type profileType)
    {
       Mapper.Configuration.AddProfileThreadSafe(Activator.CreateInstance(profileType) as Profile);
    }
}
最后把Filter应用到Controller的Action
[AutoMapperConfigurationActionFilter(typeof(OrderDomainMvcProfile))]
public virtual ActionResult OrderGrid_Select(GridCommand command)
{ ……        
}


这里介绍另外一种比较特别的方法。我希望在程序刚刚开始启动,即Application_Start的时候,就完成所有的配置,一劳永逸。如果ASP.NET MVC有多个Domain对应多个Area,那么在global.asax.cs中Application_Start中就要写很多配置AutoMapper的代码。这里我们使用反射,去寻找DLL中实现了IStartupTask的接口的方法,然后运行Excecute方法即可。

创建一个IStartupTask接口

public interface IStartupTask
{
    void Execute();
}
实现这个接口
public class AutoMapperStartupTask : IStartupTask
 {
        public void Execute()
        {
           
            Create<User, UserModel>();
            Create<Widget, WidgetModel>();
            Create<WidgetDefinition, WidgetDefinitionModel>();

            //Mapper.CreateMap<ModuleDefinition, ModuleDefinitionModel>()
            //  .ForMember(m => m.AppId, o => o.MapFrom(e => e.App == null ? (int?)null : e.App.Id))
            //  .ForMember(m => m.AppTitle, o => o.MapFrom(e => e.App == null ? null : e.App.Title));
            //Mapper.CreateMap<ModuleDefinitionModel, ModuleDefinition>();

        }

        protected virtual void Create<T1, T2>()
        {
            Mapper.CreateMap<T1, T2>();
            Mapper.CreateMap<T2, T1>();
        }
 }

在Global.ascx中一次性引入所有的AutoMapper配置
protected void Application_Start()
{
     ……
     ExecuteStartupTasks();
}


private void ExecuteStartupTasks()
{
            List<IStartupTask> startupTasks = new List<IStartupTask>();
            Assembly asm = this.ExecutingAssembly;

            // get path of executing (bin) folder from the current executing assembly
            string codeBase = this.ExecutingAssembly.CodeBase;
            UriBuilder uri = new UriBuilder(codeBase);
            string path = Uri.UnescapeDataString(uri.Path);
            string bin = Path.GetDirectoryName(path);
            string[] assemblies = Directory.GetFiles(bin, "*.dll");

            foreach (String file in assemblies)
            {
                try
                {
                    if (File.Exists(file))
                    {
                        // load the assembly
                        asm = Assembly.LoadFrom(file);

                        // get all types from the assembly that inherit IStartupTask
                        var query = from t in asm.GetTypes()
                                    where t.IsClass && t.GetInterface(typeof(IStartupTask).FullName) != null
                                    select t;

                        // add types to list of startup tasks
                        foreach (Type type in query)
                        {
                            startupTasks.Add((IStartupTask)Activator.CreateInstance(type));
                        }
                    }
                }
                catch (Exception ex)
                {
                    Exceptions.LogException(ex);
                }
            }

            // execute each startup task
            foreach (IStartupTask task in startupTasks)
            {
                task.Execute();
            }
}

你可能感兴趣的:(AutoMapper的配置方法)