Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ExpressMapper crashes when Mapper.Compile() is called: Default constructor not found #144

Open
SuheylZ opened this issue Oct 13, 2017 · 4 comments

Comments

@SuheylZ
Copy link

SuheylZ commented Oct 13, 2017

I have the following classes for which I'm using the ExpressMapper.

 public class EquipmentRequirementEditModel: IObjectBinder
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Equipment { get; set; }
        public string ManualId { get; set; }
        public string Maintanence { get; set; }
        public string Tools { get; set; }
        public string Notes { get; set; }

        public DropDownList<int> Facility { get; set; } = new DropDownList<int>();
        public DropDownList<int> Frequency { get; set; } = new DropDownList<int>();
        public DropDownList<int> Position { get; set; } = new DropDownList<int>();

        public void Bind(IMappingServiceProvider p)
        {
            p.Register<Requirement, EquipmentRequirementEditModel>()
                .Member(t => t.Id, s => s.RequirementId)
                .Member(t => t.Title, s => s.RequirementTitle)
                .Member(t => t.Equipment, s => s.Equipment.EquipmentTitle)
                .Member(t => t.ManualId, s => s.Equipment.ManualId)
                .Member(t => t.Maintanence, s => s.Requirement1)
                .Member(t => t.Tools, s => s.Requirement2)
                .After((s, t) =>
                {
                    t.Facility.Selection = s.FacilityId;
                    t.Frequency.Selection = s.FrequencyId.Value;
                    t.Position.Selection = s.PostId;
                });

            p.Register<EquipmentRequirementEditModel, Requirement>()
                .Ignore(t => t.RequirementId)
                .Member(t => t.RequirementTitle, s => s.Title)
                .Value(t => t.IsPrimary, true)
                .Member(t => t.Requirement1, s => s.Maintanence)
                .Member(t => t.Requirement2, s => s.Tools)
                .Member(t => t.Notes, s => s.Notes)
                .Member(t => t.FacilityId, s => s.Facility.Selection)
                .Member(t => t.FrequencyId, s => s.Frequency.Selection)
                .Member(t => t.PostId, s => s.Position.Selection)
                .After((s, t) =>
                {
                    t.FacilityId = s.Facility.Selection;
                    t.FrequencyId = s.Frequency.Selection;
                    t.PostId = s.Position.Selection;
                });
    }

    public partial class Requirement
    {
        public int RequirementId { get; set; }
        public int CompanyId { get; set; }
        public int FacilityId { get; set; }
        public Nullable<int> EquipmentId { get; set; }
        public string RequirementTitle { get; set; }
        public Nullable<bool> IsPrimary { get; set; }
        public string Requirement1 { get; set; }
        public string Requirement2 { get; set; }
        public Nullable<int> FrequencyId { get; set; }
        public int PostId { get; set; }
        public string Notes { get; set; }
    
        public virtual Company Company { get; set; }
        public virtual Equipment Equipment { get; set; }
        public virtual Facility Facility { get; set; }
        public virtual Frequency Frequency { get; set; }
        public virtual Post Post { get; set; }
    }

However I always get this exception. It can be noted that the above two classes can be instaintiated directly and require no special initialization for instance:

var entity = new Requirement();
var model = new EquipmentRequirementEditModel();

Here is the stacktrack from ExpressMapper:

Error Could not initialize application object properly. See the stacktrace for more detail ExpressMapper.ExpressmapperException: Error error occurred trying to compile mapping for: source Models.EquipmentRequirementEditModel, destination Entities.Requirement. See the inner exception for details. ---> System.MissingMethodException: No parameterless constructor defined for this object.
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at System.Activator.CreateInstance(Type type)
at ExpressMapper.MappingServiceBase.GetMapExpressions(Type src, Type dest) in C:\Source\ExpressMapper\Expressmapper.Shared\MappingServiceBase.cs:line 58
at ExpressMapper.SourceMappingService.MapProperty(Type srcType, Type destType, Expression srcExpression, Expression destExpression, Boolean newDest) in C:\Source\ExpressMapper\Expressmapper.Shared\SourceMappingService.cs:line 78
at ExpressMapper.MappingServiceBase.GetDifferentTypeMemberMappingExpression(Expression srcExpression, Expression destExpression, Boolean newDest) in C:\Source\ExpressMapper\Expressmapper.Shared\MappingServiceBase.cs:line 313
at ExpressMapper.MappingServiceBase.GetMemberMappingExpression(Expression left, Expression right, Boolean newDest) in C:\Source\ExpressMapper\Expressmapper.Shared\MappingServiceBase.cs:line 186
at ExpressMapper.TypeMapperBase2.MapMember(MemberExpression left, Expression right) in C:\Source\ExpressMapper\Expressmapper.Shared\TypeMapperBase.cs:line 249 at ExpressMapper.TypeMapperBase2.AutoMapProperty(MemberInfo propertyGet, MemberInfo propertySet) in C:\Source\ExpressMapper\Expressmapper.Shared\TypeMapperBase.cs:line 206
at ExpressMapper.TypeMapperBase2.ProcessAutoProperties() in C:\Source\ExpressMapper\Expressmapper.Shared\TypeMapperBase.cs:line 326 at ExpressMapper.SourceTypeMapper2.CompileInternal() in C:\Source\ExpressMapper\Expressmapper.Shared\SourceTypeMapper.cs:line 40
at ExpressMapper.TypeMapperBase`2.Compile(CompilationTypes compilationType, Boolean forceByDemand) in C:\Source\ExpressMapper\Expressmapper.Shared\TypeMapperBase.cs:line 119
--- End of inner exception stack trace ---

@SuheylZ SuheylZ changed the title ExpressMapper crashes when Mapper.Compile() is used: Default constructor not found ExpressMapper crashes when Mapper.Compile() is called: Default constructor not found Oct 13, 2017
@FSou1
Copy link

FSou1 commented Oct 13, 2017

Entities.Requirement. See the inner exception for details. ---> System.MissingMethodException: No parameterless constructor defined for this object.

Are you sure that you don't have constructor for a Requirement entity? It's declared with a partial keyword.

@SuheylZ
Copy link
Author

SuheylZ commented Oct 13, 2017

that is a class generated by Entity Framework, hence the partial keyword. but No, it cab be instantiated on its own and that's how I have used it in the code.
that's exactly what's problem that i can't figure out even after spending hours. why does it complain about not having a default constructor.
and here is what i call brain fuck. the two classes when combined with other classes, expressmapper does not complain about any default constructor for either of them and they work. so what's so special about this combination? do these classes hate each other?

@SuheylZ
Copy link
Author

SuheylZ commented Oct 15, 2017

from the documentation I tried this so that it would not have to create the object itself but it still gives the same error.

            p.Register<EquipmentRequirementEditModel, Requirement>()
                    .InstantiateFunc((s) => {
                        var t = new Requirement();
                        t.IsPrimary = true;
                        return t;
                    })
                    .Member(t => t.RequirementTitle, s => s.Title)
                    .Member(t => t.Requirement1, s => s.Maintanence)
                    .Member(t => t.Requirement2, s => s.Tools)
                    .Member(t => t.Notes, s => s.Notes)
                    .After((s, t) =>
                    {
                        t.FacilityId = s.Facility.Selection;
                        t.FrequencyId = s.Frequency.Selection;
                        t.PostId = s.Position.Selection;
                    })
                    .CompileTo(CompilationTypes.Destination);

@Calabonga
Copy link

Looks like my issue already described, but I want confirm that issue exists. I have a sample which works perfectly
image

And have a PagedListConverter used in previous screenshot
image

Now I want to use generic method (in generic class) for selecting paged list collection (I'm using PagedList )
image

But the error occurs like mentioned in title of the issue
image

I don't understand why it happens because in first screenshot code this mapping works perfectly. Furthermore, all used Models and ViewModels have default constructor. Concerning PagedList, a specilficallly for that is used PagedListResolver (it works great in second screenshot).

I'm trying to use your mapper instead if my favorite (for this time) AutoMapper. If I can resolve this issue, your mapper become my favorite (for many reasons). Please help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants