Code Monkey home page Code Monkey logo

automapper's Introduction

AutoMapper

CI NuGet MyGet (dev) Documentation Status

What is AutoMapper?

AutoMapper is a simple little library built to solve a deceptively complex problem - getting rid of code that mapped one object to another. This type of code is rather dreary and boring to write, so why not invent a tool to do it for us?

This is the main repository for AutoMapper, but there's more:

How do I get started?

First, configure AutoMapper to know what types you want to map, in the startup of your application:

var configuration = new MapperConfiguration(cfg => 
{
    cfg.CreateMap<Foo, FooDto>();
    cfg.CreateMap<Bar, BarDto>();
});
// only during development, validate your mappings; remove it before release
#if DEBUG
configuration.AssertConfigurationIsValid();
#endif
// use DI (http://docs.automapper.org/en/latest/Dependency-injection.html) or create the mapper yourself
var mapper = configuration.CreateMapper();

Then in your application code, execute the mappings:

var fooDto = mapper.Map<FooDto>(foo);
var barDto = mapper.Map<BarDto>(bar);

Check out the getting started guide. When you're done there, the wiki goes in to the nitty-gritty details. If you have questions, you can post them to Stack Overflow or in our Gitter.

Where can I get it?

First, install NuGet. Then, install AutoMapper from the package manager console:

PM> Install-Package AutoMapper

Or from the .NET CLI as:

dotnet add package AutoMapper

Do you have an issue?

First check if it's already fixed by trying the MyGet build.

You might want to know exactly what your mapping does at runtime.

If you're still running into problems, file an issue above.

License, etc.

This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our community. For more information see the .NET Foundation Code of Conduct.

AutoMapper is Copyright © 2009 Jimmy Bogard and other contributors under the MIT license.

.NET Foundation

This project is supported by the .NET Foundation.

automapper's People

Contributors

agentfire avatar angelinsky7 avatar antoinebj avatar asbjornu avatar bfcamara avatar blaised avatar blemasle avatar dnikolovv avatar gabemilani avatar gentledepp avatar hazzik avatar jbogard avatar jnm2 avatar jogibear9988 avatar joshuaflanagan avatar killergege avatar kobbikobb avatar lbargaoanu avatar lxalln avatar mjalil avatar moudrick avatar pdudnikov avatar rubengonzalezlodeiro avatar stehlikio avatar sunnycase avatar tasteful avatar timmi-on-rails avatar tornhoof avatar tylercarlson1 avatar venzhyk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

automapper's Issues

Automapper

Ours[CodePlex]
When I add the Automapper assembly as reference to my project, I get an error about it requiring System.Web. I don't see why this would be the case of a way around it.

Bidirectional many-to-one relationships not mapped for multiple levels

GarethC[CodePlex]
NUnit test demonstrating problem attached.

A town has many streets (each of which has a town), a street has many houses (each of which has a street).
Mapping a hierarchy between two such identical looking data structures maps the street / house relationship correctly (i.e. the street property on each house within a street is equal to the street in question). However, the town/street relationshyip is not mapped correctly when there is more than one street in the town (i.e. for the second street, town.street[1].town does not equal town).

Unable to build using go.bat or go-full.bat

there seems to be a problem with the build batch files and nunit. It complains that nunit binary 2.2.2.8 is not found and binary redirect should be used. I pulled the latest nunit and updated my fork, but now there's a problem in .net4 is not a valid specification for nant (guessing).

Any thoughts on how to get this to resolve?

Thanks,
-Steve

Allow flattening of collection items

jbogard[CodePlex]
Right now flattening only works for non-collection types. If I have a source type of:

class Product
{
public string Name { get; set; }
}

I can't do something like this:

class Catalog
{
IEnumerable<Product> GetProducts();
}

class CatalogDto
{
public string[] ProductsName { get; set; }
}

Wrong mapping when using expression d=>d as destination

ReflectionHelper.FindProperty does not handle case when expression do not have a destination property.

using System.Collections.Generic;

namespace ConsoleApplication10
{
using AutoMapper;

class Program
{
    public class SourceObject
    {
        public SourceItem[] Items { get; set; }
    }

    public class SourceItem
    {
        public string Name { get; set; }
    }

    public class DestItem
    {
        public string Value { get; set; }
    }

    static void Main(string[] args)
    {
        var src = new SourceObject
        {
            Items = new[]
            {
                new SourceItem { Name = "One" }
            }
        };

        Mapper.CreateMap<SourceItem, DestItem>().ForMember(d => d.Value, opt => opt.MapFrom(s => s.Name));
        Mapper.CreateMap<SourceObject, IList<DestItem>>().ForMember(d => d, opt => opt.MapFrom(s => s.Items));

        var r = Mapper.Map<SourceObject, IList<DestItem>>(src);
    }
}

}

UsingConvert configuration dose not work

atiehra[CodePlex]
For mapping database side objects to dto objects, I am using auto mapper. these two kind of objects are in independent projects and the project witch contains dto objects has a reference to another project. I dont have any problem with mapping real objects to dtos. but in a special case ,the real object has some relations to the other objects and dto object should flatten it, then I have to use "using Convert" method, but it seems that this configuration wont work if I use it in dto project and I have to reconfigure it in the other project. how can I solve this prpoblem without reconfiguring mapping ?

opt.Condition not working when the getter source property throws an exception

I have a mapping like:

                .ForMember(dest => dest.Domicilio, opt => {
                    opt.Condition(x => !x.IsEmp_DomicilioNull());
                    opt.MapFrom(orig => orig.Emp_Domicilio);
                                                      })

I got this exception:

Exception of type 'AutoMapper.AutoMapperMappingException' was thrown. ---> System.Data.StrongTypingException: No se puede obtener el valor porque es DBNull. ---> System.InvalidCastException: Unable to cast object of type 'System.DBNull' to type 'System.String'.
at EmpresasDS.IS_EmpresaRow.get_Emp_Domicilio()
--- End of inner exception stack trace ---
at EmpresasDS.IS_EmpresaRow.get_Emp_Domicilio()
at Business.EmpresaManager.b__9(IS_EmpresaRow orig) in C:\BusinessLayer\Business\EmpresaManager.cs:line 114
at AutoMapper.DelegateBasedResolver`2.Resolve(ResolutionResult source) in C:\Code Libs\jbogard-AutoMapper-8ec7940\src\AutoMapper\Internal\DelegateBasedResolver2.cs:line 23
at AutoMapper.PropertyMap.ResolveValue(ResolutionContext context) in C:\Code Libs\jbogard-AutoMapper-8ec7940\src\AutoMapper\PropertyMap.cs:line 71
at AutoMapper.Mappers.TypeMapObjectMapperRegistry.PropertyMapMappingStrategy.MapPropertyValue(ResolutionContext context, IMappingEngineRunner mapper, Object mappedObject, PropertyMap propertyMap) in C:\Code Libs\jbogard-AutoMapper-8ec7940\src\AutoMapper\Mappers\TypeMapObjectMapperRegistry.cs:line 94

This happens beacuse even the property is conditioned, the getter method of the source property throws an exception if it's called when that condition doesn't apply.

The solution is to track where the Getter is called without evaluating the Condition.

A workaround is using a custom Resolver.

As side note, this happens when a DataSet allows nulls, and it has a null value.

Best Regards,

ReflectionPermission issue when running in WCF service

dewang[CodePlex]
The code throws a SecurityAccessDeniedException when used from a WCF service. The app is in full trust mode but still throw this -
{"Request for the permission of type 'System.Security.Permissions.ReflectionPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed."}

at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
at System.Security.CodeAccessPermission.Demand()
at System.Reflection.Emit.DynamicMethod.PerformSecurityCheck(Type owner, StackCrawlMark& stackMark, Boolean skipVisibility)
at System.Reflection.Emit.DynamicMethod..ctor(String name, Type returnType, Type[] parameterTypes, Type owner, Boolean skipVisibility)
at AutoMapper.DelegateFactory.CreateDynamicMethod(MemberInfo member, Type sourceType)
at AutoMapper.DelegateFactory.CreateSet(PropertyInfo property)
at AutoMapper.Internal.PropertyAccessor..ctor(PropertyInfo propertyInfo)
at AutoMapper.ReflectionHelper.ToMemberAccessor(MemberInfo accessorCandidate)
at AutoMapper.TypeMapFactory.CreateTypeMap(Type sourceType, Type destinationType, IMappingOptions options)
at AutoMapper.Configuration.CreateTypeMap(Type source, Type destination, String profileName)
at AutoMapper.Configuration.CreateMap[TSource,TDestination](String profileName)
at AutoMapper.Configuration.CreateMap[TSource,TDestination]()
at AutoMapper.Mapper.CreateMap[TSource,TDestination]()
at IE.Servicing.Cards.AccountSummary.Service.AccountService.SetCustomerBackofficeIdentifiers(Collection`1 identifiers, IGetAccountsRequest request)
at IE.Servicing.Cards.AccountSummary.Service.AccountService.GetDefaultAccount(Collection`1 backofficeIdentifiers)
at IE.Servicing.Cards.AccountSummary.Service.AccountInformation.GetDefaultAccount(Collection`1 backofficeIdentifiers)
at SyncInvokeGetDefaultAccount(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)


A fix is to add an assert for the required permission
new ReflectionPermission(ReflectionPermissionFlag.ReflectionEmit).Assert();

Write Only Properties ignored by Automapper

Automapper is ignoring anything that doesn't have both a get & a set. For instance, given the following interface Automapper won't call the set on the CodedErrors property.

interface IMyView
{
IList CodedErrors { set; }
}

ForAllMembers() breaks fluent syntax

Change signature of IMappingExpression<Source, Destination>
void ForAllMembers() to return IMappingExpression<Source, Destination> because it breaks fluent syntax
(see #31)

Map using constructor instead of properties

jlembke[CodePlex]
In some cases the type I'm mapping to may have private setters, and I might want to map my src to constructor parameters instead.
1) Is that even advisable, and am I not thinking about this correctly
2) How would I do that?

Thanks,
Jeff

Mapping objects and dtos

atiehra[CodePlex]
I need to map an object to a dto object and vs. In mapping configuration for mapping dto to object I use "using convert" method. I dont know if I have to use this method for the opposite side. my question is that is it necessary to use the method in both case or I can map one side in a simple way?

Currency symbol in unit tests

Two unit tests fail when run in non-US locale in strings.cs and profiles.cs because of hard coded "$".
Change code to use NumberFormatInfo.CurrentInfo.CurrencySymbol, e.g.
listViewModel.Amount.ShouldEqual(NumberFormatInfo.CurrentInfo.CurrencySymbol + "50.00");
and
result.ShouldEqual(NumberFormatInfo.CurrentInfo.CurrencySymbol + "5,343.15");

Inheritance security rules violated while overriding member

I am getting this error when I call Mapper.Map, I beleive it has something to do with some new security options in .Net 4.0.

Inheritance security rules violated while overriding member: 'Castle.Core.Logging.LevelFilteredLogger.InitializeLifetimeService()'. Security accessibility of the overriding method must match the security accessibility of the method being overriden.

Not sure if this is related to AutoMapper or Castle.Core though.

Nested mapping between two collection properties does not working when destination only has a getter

metaman[CodePlex]
I guess this is not really a bug but is by design, however it would be great if there was a decent solution to this. Basically our destination objects are not under our control and they have a number of properties which are collections and follow the pattern:

private readonly List<Something> listOfSomething = new List<Something>();

public List<Something> ListOfSomething {get { return listOfSomething; } }

- When I setup the mapper to map to these properties from other collection properties, these mappings do not work. Is there are a way to solve this? I appreciate that it obviously can't create a new instance of the target property but for collections could there not be an alternative which can populate an existing instance?

ForAllMembers -> Ignore() overwrites already defined mappings.

I need to map only one property (PrimaryKeyColumnName ) and ignore all
others:

class TableMappingInfo {
public string IdentityFieldName{ get;set; }
... other properties
}

class GridTableInfo {
public string PrimaryKeyColumnName { get; set; }
...
}

Configuration code looks like this:
Mapper.Map<TableMappingInfo, GridTableInfo>()
.ForMember(gti => gti.PrimaryKeyColumnName, opt => opt.MapFrom(m =>
m.IdentityFieldName)
.ForAllMembers(opt=>opt.Ignore());

But when I'm using following code to map it does not map
PrimaryKeyColumnName:

Mapper.Map(tableMapping, gridTableInfo);

If I change code to manually ignore all other properties, it works
fine.

I'm using Automapper/NE T3.5 version 2.0.0.4

Below is unit-test code:

[TestFixture]
public class Class1
{
    public class Source

    {
        public string IdentityFieldName { get; set; }
        public string IgnoredField2 { get; set; }
    }


    public class Destination

    {
        public string PrimaryKeyColumnName { get; set; }

        public string IgnoredField1 { get; set; }
    }

    #region Tests

    [Test]
    public void ForAllMembers_ShouldSkip_AlreadyDefinedMappings()
    {
        Mapper.Reset();
        Mapper.CreateMap<Source, Destination>()
            .ForMember(dst => dst.PrimaryKeyColumnName, src => src.MapFrom(m => m.IdentityFieldName))
            .ForAllMembers(opt => opt.Ignore());

        Mapper.AssertConfigurationIsValid();
        var dest = new Destination {IgnoredField1 = "1"};
        var source = new Source {IdentityFieldName = "id", IgnoredField2 = "2"};

        Mapper.Map(source, dest);

        Assert.AreEqual("id", dest.PrimaryKeyColumnName);
        Assert.AreEqual("1", dest.IgnoredField1);


    }

    #endregion
}

Fail to map System.Nullable<enumType> (Specified cast is not valid in generated (emit) code)

This code will fail with lastest version:

class Program
{
    static void Main(string[] args)
    {
        Rec r = new Rec
        {
            settlement_type = 1
        };

        AutoMapper.Mapper.CreateMap(typeof(Rec), typeof(Dto));
        var dto = AutoMapper.Mapper.Map(r, typeof(Rec), typeof(Dto));
    }
}

public class Dto
{
    public settlement_type? settlement_type { get; set; }
}

public class Rec : IDataRecord
{
    public int? settlement_type { get; set; }

    #region IDataRecord Members

    public int FieldCount
    {
        get { return 1; }
    }

    public bool GetBoolean(int i)
    {
        throw new NotImplementedException();
    }

    public byte GetByte(int i)
    {
        throw new NotImplementedException();
    }

    public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
    {
        throw new NotImplementedException();
    }

    public char GetChar(int i)
    {
        throw new NotImplementedException();
    }

    public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
    {
        throw new NotImplementedException();
    }

    public IDataReader GetData(int i)
    {
        throw new NotImplementedException();
    }

    public string GetDataTypeName(int i)
    {
        throw new NotImplementedException();
    }

    public DateTime GetDateTime(int i)
    {
        throw new NotImplementedException();
    }

    public decimal GetDecimal(int i)
    {
        throw new NotImplementedException();
    }

    public double GetDouble(int i)
    {
        throw new NotImplementedException();
    }

    public Type GetFieldType(int i)
    {
        return typeof(settlement_type);
    }

    public float GetFloat(int i)
    {
        throw new NotImplementedException();
    }

    public Guid GetGuid(int i)
    {
        throw new NotImplementedException();
    }

    public short GetInt16(int i)
    {
        throw new NotImplementedException();
    }

    public int GetInt32(int i)
    {
        throw new NotImplementedException();
    }

    public long GetInt64(int i)
    {
        throw new NotImplementedException();
    }

    public string GetName(int i)
    {
        return "settlement_type";
    }

    public int GetOrdinal(string name)
    {
        return 0;
    }

    public string GetString(int i)
    {
        throw new NotImplementedException();
    }

    public object GetValue(int i)
    {
        throw new NotImplementedException();
    }

    public int GetValues(object[] values)
    {
        throw new NotImplementedException();
    }

    public bool IsDBNull(int i)
    {
        return false;
    }

    public object this[string name]
    {
        get { throw new NotImplementedException(); }
    }

    public object this[int i]
    {
        get { return settlement_type; }
    }

    #endregion
}

public enum settlement_type
{
    PreDelivery = 0,
    DVP = 1,
    FreeDelivery = 2,
    Prepayment = 3,
    Allocation = 4,
    SafeSettlement = 5,
}

I think that DataReaderMapper.cs:93 is incorrect....

Mapper.Map<IEnumerable<string>, List<int>>(values) executed IEnumerable<T> twice

The following sample outputs the following:

run
run
1
2
3

This output is not expected. It is expected that the following would be written:

run
1
2
3

There is some sort of bug where the IEnumerable is called twice but not returning its values twice. It is expected that the the IEnumerable source is executed just once.

namespace AutoMapperBug
{
    using System;
    using System.Collections.Generic;

    class Program
    {
        static void Main(string[] args)
        {
            AutoMapper.Mapper.CreateMap<string, int>().ConvertUsing(src => Convert.ToInt32(src));

            var values = GetTestValues();
            List<int> result = AutoMapper.Mapper.Map<IEnumerable<string>, List<int>>(values);

            foreach (int i in result)
            {
                Console.WriteLine(i);
            }
        }

        static IEnumerable<string> GetTestValues()
        {
            Console.WriteLine("run");
            yield return "1";
            yield return "2";
            yield return "3";
        }
    }
}

Conditional mapping executes mapping function even for conditions that aren't met

Hello,

I find it confusing that automapper still executes mapping code for objects that don't meet the specified condition. Shouldn't it skip trying to map the value in the first test?
This forces me to handle properties that I'm not even trying to map. For instance, null values on reference type properties.

E.g: For the mapping below, both tests hit the TestMapping method.
Mapper.Initialize(cfg =>
{
cfg.CreateMap<Source, Destination>().ForMember(dest => dest.Value, opt => { opt.Condition(src => src.Value > 0); } opt.MapFrom(s => TestMapping(s.Value)); });
});

int TestMapping(int value) { return value + 1; }

[Test]
public void Should_skip_the_mapping_when_the_condition_is_true()
{
var destination = Mapper.Map<Source, Destination>(new Source {Value = -1});
destination.Value.ShouldEqual(0);
}

[Test]
public void Should_execute_the_mapping_when_the_condition_is_false()
{
var destination = Mapper.Map<Source, Destination>(new Source { Value = 7 });
destination.Value.ShouldEqual(7);
}

Is there a way to get it to simply skip altogether?

Support for polymorphic mappings

dimitrod[CodePlex]
I have the following classes:

class ParentSource
{
public string ParentProp { get; set; }
}

class ChildSource : ParentSource
{
public string ChildProp { get; set; }
}

class Dest
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}

And what I'm trying to achieve is to be able to map from instances of ParentSource and ChildSource to Dest like this:

* if I have an instance of ParentSource I would like to map to a Dest instance with ParentProp mapped to Prop1 and Prop2 left null.
* if I have an instance of ChildSource I would like to map to a Dest instance with ParentProp mapped to Prop1 and ChildProp mapped to Prop2.

I've tried the following mappings:

Mapper
.CreateMap<ParentSource, Dest>()
.ForMember(
dest => dest.Prop1,
opt => opt.MapFrom(src => src.ParentProp)
);

Mapper
.CreateMap<ChildSource, Dest>()
.ForMember(
dest => dest.Prop2,
opt => opt.MapFrom(src => src.ChildProp)
);

var source = new ChildSource
{
ParentProp = "parentProp",
ChildProp = "childProp"
};
var dst = Mapper.Map<ChildSource, Dest>(source);

In this case dst.Prop1 = null and dst.Prop2 = "childProp". If I repeat the ForMember mapping of Prop1 in the second CreateMap it works but that's what I am trying to avoid. Is this even possible and make sense or do I need to simply copy-paste all the rules defined for the parent mapper in the child mapper?

Kind regards,
Darin.

Support open generic types

kkozmic[CodePlex]
So that this would work instead of throwing ExecutionEngineException:
Mapper.CreateMap( typeof( Foo<> ), typeof( FooDto<> ) );
var dto = Mapper.Map<Foo<string>,FooDto<string>>(new Foo<string>( "a" ));

Map to constructor functions

I don't even know exactly what this means, but the title is the phrasing you asked me to put on here. Thanks. :)

NullReferenceException when letting automapper build a proxy

When I do the following:
Mapper.CreateMap(Of CustomerInventoryItem, CustomerInventoryItemDto().ForMember(Function(d) d.Price, Sub(opt) opt.MapFrom(Function(s) s.ProductPrice))
Mapper.AssertConfigurationIsValid()
Dim instance As CustomerInventoryItem =

Dim result = Mapper.Map(Of CustomerInventoryItem, Of CustomerInventoryItemDto)(instance)
Assert.That(result.Id, Is.EqualTo(<some id>)

Things work fine, but if I let automapper use the DTO's interface instead of the concrete type to have a proxy type generated for me, things are not so fine.

Mapper.CreateMap(Of CustomerInventoryItem, ICustomerInventoryItemDto)().ForMember(Function(d) d.Price, Sub(opt) opt.MapFrom(Function(s) s.ProductPrice))
Mapper.AssertConfigurationIsValid()
Dim instance As CustomerInventoryItem = <get an instance a CustomerInventoryItem>

Dim result = Mapper.Map(Of CustomerInventoryItem, Of ICustomerInventoryItemDto)(instance)
Assert.That(result.Id, Is.EqualTo(<some id>)  ' This throws the following NullReferenceException

System.NullReferenceException was unhandled
  Message=Object reference not set to an instance of an object.
  Source=DynamicProxyGenAssembly2
  StackTrace:
       at Castle.Proxies.ICustomerInventoryItemDtoProxy.get_Id()
  InnerException: 

The interface looks like:

    Public Interface ICustomerInventoryItemDto
       Property Id As Guid
       Property VendorShortName As String
       Property VendorProductId As Guid
       Property ItemNumber As String
       Property ProductCategoryCode As Integer?
       Property ProductDescription As String
       Property Quantity As Decimal
       Property Unit As String
       Property Pack As Short?
       Property Price As Decimal
   End Interface

Am I doing something wrong?

This is using version 1.1.0.118 as provided by NuGet within a .NET 4 project.

Does order of CreateMap matter?

Test

        [Test]
        public void included_mapping_should_inherit_base_mappings_should_not_throw()
        {
            Mapper.CreateMap<ModelObject, DtoObject>()
                .ForMember(d => d.BaseString, m => m.MapFrom(s => s.DifferentBaseString))
                .Include<ModelSubObject, DtoSubObject>();
            Mapper.CreateMap<ModelSubObject, DtoSubObject>();

            Mapper.AssertConfigurationIsValid();
        }

is valid, while

        [Test]
        public void included_mapping_should_inherit_base_mappings_should_not_throw()
        {
            Mapper.CreateMap<ModelSubObject, DtoSubObject>();

            Mapper.CreateMap<ModelObject, DtoObject>()
                .ForMember(d => d.BaseString, m => m.MapFrom(s => s.DifferentBaseString))
                .Include<ModelSubObject, DtoSubObject>();

            Mapper.AssertConfigurationIsValid();
        }

is not

make projected sourceMember accessible in PropertyMap

Hey Jimmy,

I am currently adding a feature to FluentMetadata on this fork.
Besides defining metadata in a fluent syntax, FluentMetadata is a framework for reusing the metadata of models for view models and OR-mappings.
The feature I'm working on uses the mapping information provided by AutoMapper to copy metadata from one mapped type to the other.

Now, where's the problem?

Well, the way AutoMapper implements the projection of properties there's no clean way I know of to access the source property of a mapping like

Mapper.CreateMap()
    .ForMember(destination => destination.RenamedMember, o => o.MapFrom(source => source.NamedMember));

My suggestion is to make this sourceMember accessible making it possible to use the AutoMapper configuration as a source of information about how types map to each other and thus adding value to AutoMapper itsself.
Looking into the source several possibilities of implementing this come to my mind:

  • adding a new (nullable?) property to PropertyMap exposing the source member, either as a Func<TSource, TMember> or as MemberInfo
  • making DelegateBasedResolver<TSource, TMember> and its readonly _method field public

What do you think of this?

Kind regards, Holger

Mapping EF collections to IEnumerable

tjaskula[CodePlex]
Hello,

We're using Automapper for mapping between EF entities and our Dto's. All works well but I have a little problem for specific mapping. I'll try to make it clear.

Here's my simplified EF Entities :

public class Context : EntityObject
{
"some properties"

public EntityCollection<Context_Geo1> Context_Geo1 {get; set;}
}

public class Context_Geo1 : EntityObject
{
public int IdContextGeo
public int? IdContext
public int? IdGeo
}

Here my "Signle" Dto

public class ContextDto
{
"some properties"

public IEnumerable<int> StructureGeo1 {get; set;}
}

What I need to do is to map from Entity to Dto. I need to map idGeo property from Context_Geo1 to ContextDto.StructureGeo1.

I did a CustomValueResolver for that and configured my map like this.

Mapper.CreateMap<Context, ContextDto>().FormMember(p => p.StructureGeo1, opt => opt.Ignore());
Mapper.CreateMap<Context_Geo1, int>().ForMember(p => p, opt => opt.ResolveUsing<ContextValueResolver>());

Where ContextValueResolver returns Context_Geo1.IdGeo (an int as I want).

When I run that I have several Automapper exceptions like this (right after my custom resolver was called which for tests returns 1) :

Test method Bali.Offer.Tests.Data.DataMapperTests.ContextShouldBeMappedFromEntityToDto threw exception:
AutoMapper.AutoMapperMappingException: Trying to map System.Data.Objects.DataClasses.EntityCollection`1[[Bali.Offer.Data.Context_Geo1, Bali.Offer.Data, Version=0.4.0.0, Culture=neutral, PublicKeyToken=null]] to System.Collections.Generic.IEnumerable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].
Exception of type 'AutoMapper.AutoMapperMappingException' was thrown. ---> AutoMapper.AutoMapperMappingException: Trying to map Bali.Offer.Data.Context_Geo1 to System.Int32.
Using mapping configuration for Bali.Offer.Data.Context_Geo1 to System.Int32
Exception of type 'AutoMapper.AutoMapperMappingException' was thrown. ---> System.NullReferenceException: Object reference not set to an instance of an object.

I don't know if I'm doing it well. Thanks for your help.

Thomas

Unit tests not executed after adding reference to AutoMapper (resolved)

michelc[CodePlex]
Why are all my Visual Studio test results “Not executed” : http://stackoverflow.com/questions/525578/why-are-all-my-visual-studio-test-results-not-executed

-----

This is not really a bug but rather a request for assistance. I am trying to follow the tutorial "The Big Boy MVC Series" (http://www.weirdlover.com/2010/07/01/the-big-boy-mvc-series-part-22-whoop/).

In part 22, step 5, we have to add a reference to AutoMapper. What I did in the two projects (Web & Test) . But immediatly after that, all my unit tests do not run any more. As you can see, they don't fail, they are just "Not Executed" : http://twitpic.com/21p30v

Features of my solution:
- MVC 2
- ASP.NET 3.5
- Visual Studio 2008 in French
- AutoMapper.dll: 1.1.0.188

Does anyone has had this kind of problem?

Merci.
Michel

Multithreading support

vilia[CodePlex]
There is no support for multithreading work now as I see. I think it would be good desing choose to redevelop from static objects to non-static objects, like:
MapperInstance mapper = Mapper.CreateMapper();
mapper.CreateMap<TA, TB>();
.....
var result = mapper.Map<TA, TB>(source);

NullReferenceException for String to Enum

For string to enum mapping, Line 17 in EnumMapper.cs:
return Enum.Parse(context.DestinationType, context.SourceValue.ToString(), true);
throws NullReferenceException when passed string is null.

Probably a more appropriate custom exception or ArgumentException would be better.

Even better option would be instead of throwing exception; set to default value of 0 when mapping from null or empty string to an enum type.

Rev. 141 breaks nested mappings

chakarov[CodePlex]
Changes in rev. 141 in Configuration.cs break nested mapping when base class is used. See attached unit test.

support for attribute mappings

we use data annotations on our models that are supposed to generate bits of JavaScript on page. But when I use AutoMapper to map our models to view models we lose these data annotation attributes

Since AutoMapper already includes Castle.DynamicProxy, it seems like it wouldn't be too difficult to proxy classes as well as interfaces and copy over the Attributes.

public class CategoryModel {
    [NotNullNotEmpty(Message = "CategoryName must contain a value.")]
    [Length(Message = "CategoryName length is not valid", Min = 1, Max = 255)]
    public virtual string CategoryName { get; set; }
}

could map nicely to a view model that doesn't duplicate the attributes

public class CategoryViewModel {
    public virtual string CategoryName { get; set; }
}

Perhaps any destination class with all virtual members can be proxied (or just proxy virtual members). Then maybe a slight twist on the mapping:

Mapper.CreateMap<CategoryModel, CategoryViewModel>()
    .ForMember(x => x.CategoryName, opts => opts.MapAttributes());

or maybe

Mapper.CreateMap<CategoryModel, CategoryViewModel>()
    .ForAllMembers(opts => opts.MapAttributes());

The actual CategoryViewModel object returned by Mapper.Map should actually be a Castle.CategoryViewModelProxy (or whatever) that extends CategoryViewModel and has NotNullNotEmpty and Length attributes on it's CategoryName property.

Regardless of whether or not you agree with the design of this particular use case, this could have lots of other powerful AOP implications.

Mapping an array which is null becomes an empty array

boswald[CodePlex]
Hey Guys,

I am mapping an array in a class. In my source class it is null but when it gets mapped it becomes an array of 0 size.

I have tried the :

Mapper.Initialize(c =>
{
c.AllowNullDestinationValues = true;
});

option but this does not keep the array as a null value and instead creates the array of empty size.

Is there a way I can get the array to stay null? or is this a bug?

Count Of IEnumerable`1

Should property ProductsCount be automatically maped from IEnumerable`1 Products in followed configuration?

class Category {
    public IEnumerable<Product> Products {get;set;}
}

class CategoryDto {
   public int ProductsCount {get;set;}
}

ForAllMembers() bug where mapping config for Dest is already configured

(FYI.. moved this issue from CodePlex: http://automapper.codeplex.com/workitem/6346 to github)

Given this scenario:

public class Source
{
public int Int1 { get; set; }
public string String1 { get; set; }
public bool Bool1 { get; set; }
}

public class Destination
{
public int Int1 { get; set; }
public string String1 { get; set; }
public bool Bool1 { get; set; }
}

public class WrapperSource
{
public Source Source { get; set; }
}

First I configure the Source->Destination mapping as so:
Mapper.CreateMap<Source, Destination>();

Now, I want to map WrapperSource to Destination. Since WrapperSource already has a Source object, I should be able to configure this mapping fairly easily via the ForAllMembers() method, like so:
Mapper.CreateMap<WrapperSource, Destination>()
.ForAllMembers(opt => opt.MapFrom(src => src.Source));

No such luck. Logically, it seems like that should work but doesn't. :(

License missing

I was looking at using AutoMapper for a project at work. Unfortunately, I've got to run everything through legal and they like it when the license is well defined. I couldn't find a license for AutoMapper.

I'd love it if it were licensed under the MIT license (legal approves of it).

Thoughts?

Map From dictionary of values

ImaginaryDev[CodePlex]
Mapper won't map values from an indexable list of properties.

For example:
destination:

public interface IAmAnEmployee
{
string UserName { get; set; }
string LastName { get; set; }
}
source:

var d = new Dictionary<string, string>() { { "UserName", "user1" }, { "LastName", "Smith" } };

I understand I could manualy map these 2 properties with .ForMember, however this is a small example, the real interface is actually 9 properties, and I 5 more interfaces that I would like to use an index based mapping. The actual index type I'm trying to map from is System.Web.Mvc.FormCollection.

AssertConfigurationIsValid false positives after .ForAllMembers(opt => opt.Ignore());

klaus3b[CodePlex]
Automapper.AssertConfigurationIsValid reports missing mappings after all members are set to ignore.

(See unittest below)
------------------------------------
using NUnit.Framework;

namespace AutoMapper.UnitTests.Bug
{
[TestFixture]
public class AssertConfigIsValid
{
private class ModelObjectNotMatching
{
public string Foo_notfound { get; set; }
public string Bar_notfound;
}

private class ModelDto
{
public string Foo { get; set; }
public string Bar;
}

[Test]
// [Ignore("maybe bug. Posted to codeplex-forum 22.4.2010")]
public void ForAllIgnore()
{
Mapper.CreateMap<ModelObjectNotMatching, ModelDto>()
.ForAllMembers(opt => opt.Ignore());
Mapper.AssertConfigurationIsValid(); // should not fail
}
}
}

Strange behavior when mapping inner collection

brunofig[CodePlex]
Hi,
i'm getting a strange behavior when mapping inner collection. What happens is that the inner property isn't correctly filled. But if I map the inner property I get the mapping done. As shown in the sample bellow, the call to the map the collection to the _to variable works, but when I map the _message variable, the _message.To has 0 items.

Any thoughts why?
Thanks

//Configuration
Mapper.CreateMap<MailMessage, System.Net.Mail.MailMessage>();

Mapper.CreateMap<MailAddress, System.Net.Mail.MailAddress>()
.ConstructUsing(x => new System.Net.Mail.MailAddress(x.Address));

Mapper.CreateMap<MailAddressCollection, System.Net.Mail.MailAddressCollection>()
.ConvertUsing(new MailAddressCollectionConverter());

Mapper.AssertConfigurationIsValid(); // ALL OK :)

public void Send(MailMessage message)
{
var _to = Mapper.Map<MailAddressCollection, System.Net.Mail.MailAddressCollection>(message.To); // OK _To.Count = 1 has expected
System.Net.Mail.MailMessage _message = Mapper.Map<MailMessage, System.Net.Mail.MailMessage>(message); // NOT OK _message.To.Count = 0 :(



internal class MailAddressCollectionConverter : ITypeConverter<MailAddressCollection, System.Net.Mail.MailAddressCollection>
{
#region ITypeConverter<MailAddressCollection,MailAddressCollection> Members

public System.Net.Mail.MailAddressCollection Convert(ResolutionContext context)
{
var col = new System.Net.Mail.MailAddressCollection();

if (!context.IsSourceValueNull)
{
var source = context.SourceValue as MailAddressCollection;
if (source != null)
{
foreach (var to in source)
{
col.Add(to.Address);
}
}
}

return col;
}

#endregion
}

Multiple mappings for the same type

uliderknecht[CodePlex]
Hi,

I'd like to suggest to optionally specify a name for a mapping allowing to have multiple mappings of the same type with different configurations.

e.g. Mapper.CreateMap<Order, OrderDto>("OrderMapping");

I see a lot of value in that especially in combination with the Ignore configuration.

In one of my projects I currently implemented my own mapper which maps nested objects based on input parameters. Some of my service requests allow the consumer to specify whether nested collections are loaded. For example in one instance a consumer wants to load a collection of orders without having the details such as the products attached. In an other instance the consumer may want to retrieve orders with associated products. The mapping for both cases would be of the same type but the Ignore configuration would be different.

This is similar to unity where you can configure a type and a name to distinguish between various type configurations of the same type. :)

NHibernate generate LazyInitializationException when I map a Domain to DTO object

This happen because the hibernate session is close when I want to map from Domain to DTO object.
I made some changes in the EnumerableMapperBase class to avoid the exception and allow the autoMapper map the objects. I don't think this is the solution but it works for me, but my be latter a better solution can be added to the autoMapper to fix this problem.
Next is the class source code with my changes.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace AutoMapper.Mappers
{
public abstract class EnumerableMapperBase : IObjectMapper
where TEnumerable : IEnumerable
{
public object Map(ResolutionContext context, IMappingEngineRunner mapper)
{
if (context.DestinationType.IsAssignableFrom(context.SourceType) && context.SourceValue != null)
{
return context.SourceValue;
}

        var sourceValue = (IEnumerable)context.SourceValue ?? new object[0];
        IEnumerable<object> enumerableValue = sourceValue.Cast<object>();

        Type sourceElementType = TypeHelper.GetElementType(context.SourceType, sourceValue);
        Type destElementType = TypeHelper.GetElementType(context.DestinationType);
        var sourceLength = 0;
        bool flag = false;
        //->***********New********************
        try
        {
            //************End New**************** <-
            sourceLength = enumerableValue.Count();
            //-> ***********New********************
        }
        catch (Exception e)
        {
            if (!e.GetType().Name.Equals("LazyInitializationException"))
                throw e;
            flag = true;
        }
        //**************End New***************** <-
        var destination = (context.DestinationValue ?? CreateDestinationObject(context, destElementType, sourceLength, mapper));
        var enumerable = GetEnumerableFor(destination);

        ClearEnumerable(enumerable);
        //->***********New********************
        if (flag)
        {
            object valueToAssignTemp = destination;
            return valueToAssignTemp;
        }
        //***********End New******************** <-
        int i = 0;
        foreach (object item in enumerableValue)
        {
            var typeMap = mapper.ConfigurationProvider.FindTypeMapFor(item, sourceElementType, destElementType);

            Type targetSourceType = typeMap != null ? typeMap.SourceType : sourceElementType;
            Type targetDestinationType = typeMap != null ? typeMap.DestinationType : destElementType;

            var newContext = context.CreateElementContext(typeMap, item, targetSourceType, targetDestinationType, i);

            object mappedValue = mapper.Map(newContext);

            SetElementValue(enumerable, mappedValue, i);

            i++;
        }

        object valueToAssign = destination;
        return valueToAssign;
    }


    protected virtual TEnumerable GetEnumerableFor(object destination)
    {
        return (TEnumerable) destination;
    }

    protected virtual void ClearEnumerable(TEnumerable enumerable) { }

    private object CreateDestinationObject(ResolutionContext context, Type destinationElementType, int count, IMappingEngineRunner mapper)
    {
        var destinationType = context.DestinationType;

        if (!destinationType.IsInterface && !destinationType.IsArray)
        {
            return mapper.CreateObject(context);
        }
        return CreateDestinationObjectBase(destinationElementType, count);
    }

    public abstract bool IsMatch(ResolutionContext context);


    protected abstract void SetElementValue(TEnumerable destination, object mappedValue, int index);
    protected abstract TEnumerable CreateDestinationObjectBase(Type destElementType, int sourceLength);
}

}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.