HeroicFramework icon indicating copy to clipboard operation
HeroicFramework copied to clipboard

Class Library setup?

Open tokyo0709 opened this issue 6 years ago • 10 comments

Wondering if there is a way to setup Automapper for a class library type project?

tokyo0709 avatar Sep 26 '18 16:09 tokyo0709

You can certainly use AutoMapper in a class library project, and the latest version of Heroic.AutoMapper should work just fine. You'd just want to call HeroicAutoMapperConfigurator.LoadMapsFromAssemblyContainingTypeAndReferencedAssemblies somewhere in your application's main method, before you want to use AutoMapper.

MattHoneycutt avatar Sep 26 '18 17:09 MattHoneycutt

Gotcha. If the calling application was an Azure function would this cause a problem? I can't seem to get that call to work when I throw it in the beginning of an Azure function.

tokyo0709 avatar Sep 26 '18 23:09 tokyo0709

Hmm, I haven't tried that. Does the call throw an error? Or does it just fail to load the maps? If it's failing to load the maps, it's possible that some artifact of it running in Azure Functions is interfering with it's ability to reflect through the maps...

MattHoneycutt avatar Sep 27 '18 03:09 MattHoneycutt

Yeah. The call throws an error saying that there is no parameterless constructor for it if I remember right. I'll have to get more details when I look at it again but it didn't seem to get the mappings at all.

tokyo0709 avatar Sep 27 '18 05:09 tokyo0709

Do all of your types that implement IMapFrom, IMapTo, or IHaveCustomMappings have public, parameterless constructors?

MattHoneycutt avatar Sep 27 '18 13:09 MattHoneycutt

Ah ok yes this could be part of the problem. The class I was mapping implemented IHaveCustomMappings and properties that had getters only and only one parameterized constructor. For this reason I was attempting to setup a custom mapping that would use that constructor but I am sure I may have been doing this incorrectly.

tokyo0709 avatar Sep 27 '18 15:09 tokyo0709

Yup, that would definitely do it. HeroicAutoMapper requires that your mapping classes have public constructors.

What you could do in this case is define a separate mapping config class that implements IHaveCustomMapping. Something like this:

Model:

public class SomeModel {
   public string Something {get; private set; }
   public int SomethingElse {get; private set; }
   public SomeModel(string something, int somethingElse) {
      Something = something;
      SomethingElse = somethingElse;
   }
}

Mapping config:

public class SomeModelMappingConfig : IHaveCustomMappings
{

   public void CreateMappings(IMapperConfiguration configuration)
   {
      configuration.CreateMap<Something, SomeModel>()
                   // Mapping config here
   }
}

I've had to do this a few times in the past. I typically put the config class and the model in the same file so that the relationship is easily (re-)discoverable.

I hope that helps! I'm going to leave the issue open for now, feel free to close if this works for you.

MattHoneycutt avatar Sep 27 '18 15:09 MattHoneycutt

I just tested this and it worked perfectly. Thank you for the help! I love this library and am stoked to get it working with Azure functions as well.

tokyo0709 avatar Sep 27 '18 16:09 tokyo0709

Ok so I just ran into another problem where I have multiple Azure functions but I don't know which one is going to get hit first. In the constructor of all of them I am making that call to load the maps from the assemblies but it can only be called once it seems like or it will error out. Is there anything built out that would allow me to check if that has already been hit once?

tokyo0709 avatar Sep 28 '18 22:09 tokyo0709

Scratch that I figured out a workaround by building a static initializer. (Sorry to drag this out)

public static class AutomapperInitializer
{
    private static bool _initialized = false;

    public static void Configure()
    {
        if (!_initialized)
        {
            HeroicAutoMapperConfigurator.LoadMapsFromCallerAndReferencedAssemblies();
            _initialized = true;
        }
    }
}

And then calling,

AutomapperInitializer.Configure();

In each azure function constructor.

tokyo0709 avatar Sep 28 '18 23:09 tokyo0709