Hi James
It seems you're using Automapper with DI. Please share your DI container registration class
Hi Vincent,
I am indeed. Registration class looks like this -
[InitializableModule]
[ModuleDependency(typeof(ServiceContainerInitialization))]
public class Startup : IConfigurableModule
{
public static MapperConfiguration CreateMapperConfiguration()
{
var mappingConfig = new MapperConfiguration(config =>
{
config.AddProfile<FeaturesMappingProfile>();
config.AddProfile<ViewModelsMappingProfile>();
config.AddProfile<SearchMappingProfile>();
// NOTE: Mapping in question is in here
config.AddProfile<CatalogMappingProfile>();
});
return mappingConfig;
}
public void Initialize(InitializationEngine context)
{
RouteConfig.Configure(RouteTable.Routes);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
}
public void Uninitialize(InitializationEngine context)
{
// No logic currently required
}
public void Preload(string[] parameters)
{
// No logic currently required
}
public void ConfigureContainer(ServiceConfigurationContext context)
{
var container = context.StructureMap();
container.Configure(x =>
{
x.AddRegistry<InfrastructureRegistry>();
x.AddRegistry<FeaturesRegistry>();
x.AddRegistry<CommerceModelRegistry>();
x.AddRegistry<PimRegistry>();
var mappingConfig = CreateMapperConfiguration();
x.For<IConfigurationProvider>().Use(mappingConfig);
x.For<IMapper>().Use(mappingConfig.CreateMapper());
x.For<IClient>().Use(CreateSearchClient()).Singleton();
x.For<IBackgroundJobClient>().Singleton().Use(() => new BackgroundJobClient());
x.Scan(scan =>
{
scan.WithDefaultConventions();
scan.TheCallingAssembly();
scan.LookForRegistries();
});
});
DependencyResolver.SetResolver(new StructureMapDependencyResolver(container));
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = new StructureMapDependencyResolver(container);
GlobalConfiguration.Configuration.UseStructureMapActivator(context.StructureMap());
}
public void Configuration(IAppBuilder app)
{
// Hangfire Setup
}
private static IClient CreateSearchClient()
{
return Client.CreateFromConfig();
}
}
Hi James
It is little supicious the ServiceContainerInitialization on ModuleDependency attribute might be too earlier to register Automapper. Have you tried to change to other Initialization modules e.g. CommerceInitialization
Hi Vincent,
That does seem to resolve the runtime issue - though I'm now getting issues with the indexing (see below)... don't suppose you have any ideas around that?
An exception occurred while indexing content [Link 13] [GUID 822ab8c0-a37a-412c-9bc8-62d0f93d0e9e] [Type GlobalHomePage] [Name Corporate Homepage]: Self referencing loop detected for property 'ManifestModule' with type 'System.Reflection.RuntimeModule'. Path 'Carousel.Property[0].PrincipalAcccessor.Accessor.Method.Module.Assembly'. The loop was detected in Castle.Proxies.GlobalHomePageProxy. To correct this you can exclude one of the properties (or otherwise mapped fields) that are causing the loop by modifying the Client class' conventions. You may also modify the serializer to ignore self references. If you require the fields causing the loop to be serialized you may annotate the one of the classes in the loop with [JsonObject(IsReference = true)] or modify the JsonContract for one of the types to use IsReference = true which also can be done by modifying the Client class' conventions. (see log for more information)
You probably want to ignore the PrincipalAccessor from your content type, by adding [JsonIgnore] to it
Hi QM,
Having looked at some of our other projects, I can see the dependency on the init modules was probably fine without the one on Commerce, so the indexing is back to working.
As it stands, I can map from a ProductContent object to something else, but the error (in original) occurs when mapping to one from something else. I think the issue is with have Automapper is trying to construct a new instance of the Product - I've been trying to find a way to handle this but have so far not been successful.
I was hoping the 'ConstructUsing()' method might do the trick but the error is seemingly thrown before that gets hit... :/
I don't suppose you've ever used Automapper to map to Product or Variant content before?
In order to create content you need to use IContentFactory.CreateContent. It should work with ConstructUsing and the factory.
Hi Mark,
I was playing around with the 'ConstructUsing()' method yesterday to no avail - I've tried again today with your suggestion of using the IContentFactory but the issue seems to be that the error occurs before it ever even gets chance to hit the ConstructUsing logic...
I've tried using ConvertUsing also, since that is meant to do less stuff behind the scenes, but again, no luck with that either. I suspect I'm going to have to give up on using Automapper for this particular set of mappings since it doesn't seem like it plays nicely with Product/Variation Content.
Hi,
Currently, I have a profile like this -
I'd like to map the Dto (which contains all the data I want to add) to a new instance of the product, which I can then process further and ultimately, save to the catalog repo.
However, with my current mapping, I get the following Null Reference error on startup -
This is presumably to do with the destination model being an instance of ProductContent and thus requiring something a bit more specialized for configuring the mapping/profile...
Does anyone have any experience creating a new instance of a page/ProductContent through Automapper? The only thing similar I've been able to find around this issue was this unresolved thread in the dev-to-dev forum - https://world.episerver.com/forum/developer-forum/Developer-to-developer/Thread-Container/2018/7/automapper-custom-resolver-throws-null-exception-in-dependencyresolverinitialization/
I did try QM's suggestion in the thread above but that just resulted in responseless pages with no error message. I imagine that it (or my interpretation of it) broke the routing somehow...
This doesn't seem like anything ground-breaking, so hopefully, this is actually possible?
Any help would be greatly appreciated!
Cheers.