Where can I initialize AutoMapper mappings in an Orchard module?
Asked Answered
T

2

8

I am busy developing my first non-example Orchard module. It is a handful of controllers and views, with custom (EF) data access, and is largely independent of Orchard content types and parts. Normally I set up mappings in an Application_Start handler, but as the actions in this MVC module will be invoked in the context of the Orchard application, I no longer have that point of entry. My most obvious and immediate solution is to move mapping initialization into static constructors for mapped view models, e.g.

public class ApplicantPersonalDetailsModel : MappedViewModel<Applicant>
{
    static ApplicantPersonalDetailsModel()
    {
        Mapper.CreateMap<Applicant, ApplicantPersonalDetailsModel>().Bidirectional();
    }
    ....
}

How else can I do this? is there a better way to do this in MVC3/4 in general, or preferably, an event or hook I can grab in the Orchard application to also achieve this on applicaion startup?

Thermostat answered 21/12, 2012 at 6:24 Comment(0)
B
7

The way I have done it is by implementing IOrchardShellEvents

    public class MenuOrchardShellEvents : IOrchardShellEvents
    {
        public void Activated()
        {
            Mapper.CreateMap<YSRB.Menu.Models.Records.Customer, YSRB.Menu.Models.ViewModels.CustomerViewModel>()
                .ForMember(c => c.CustomerType, 
                    m => m.MapFrom(
                        x => (CustomerTypes)x.CustomerType
                    )
                );
            Mapper.CreateMap<YSRB.Menu.Models.ViewModels.CustomerViewModel, YSRB.Menu.Models.Records.Customer>()
                .ForMember(c => c.CustomerType,
                    m => m.MapFrom(
                        x => (int)x.CustomerType
                    )
                );
        }

        public void Terminating()
        {
            //Do nothing
        }
    }

Hope this helps.

Bringhurst answered 16/5, 2013 at 1:38 Comment(2)
Where should I put this? In a random named class inside my module and Orchard magically finds it?Howe
@Howe yes. I believe Orchard will find all classes that implement IOrchardShellEventsBringhurst
B
3

The Handler is the best place for initializing your variables, even if you haven't defined any part inside your module you can define one without a driver but with handler.

public class InitPartHandler : ContentHandler
{
    public InitPartHandler(IRepository<InitPartRecord> repository)
    {
         OnInitializing<InitPart>((context, part) =>
                 // do your initialization here
            );
    }
}

EDIT

InitPart and InitPartRecord would be  

public class InitPart : ContentPart<InitPartRecord>
{

}

public class InitPartRecord : ContentPartRecord
{

}
Barrier answered 21/12, 2012 at 7:53 Comment(2)
Can InitPartRecord then just be a dummy, i.e. empty, class? Does Orchard just call Init<part-name> on all handlers, or do I have to register a part somewhere, even if I don't write other code to define it?Thermostat
yes it can.InitPartHandler will be subscribed to handlers list by simply driving from ContentHandler.and the InitPart and InitPartRecord would be a dummy class as you mentioned.cehck my edit.Barrier

© 2022 - 2024 — McMap. All rights reserved.