Automapper Initialize Configuration does not return - possible infinite loop - automapper

We have just upgraded from Automapper 4 to Automapper 10 (I have also repeated the same problem on Automapper 8.1.1)
I am unable to initialise the Automapper. T is a Profile class with CreateMap calls.
var configuration = new MapperConfiguration(cfg =>
{
cfg.AddProfile<T>();
});
After cfg.AddProfile it disappears into endless loops and never returns. It consumes 2GB of Memory before I pull the pin (this takes a few minutes). I've debugged into AutoMapper (this is from 8.1.1) and inside MapperConfiguration it calls a method Seal(); This is where it goes into loops.
The Profile class has 1200 calls to CreateMap
Any suggestions? Automapper 4 worked well, except for a few cases where it would randomly return a null reference exception trying to find a map.
This is .Net Framework 4.7.2 and Automapper 8.1.1 (and also with Automapper 10).

Related

Upgrading Automapper and mapping zero to null based based on an attribute

I'm not very familiar with AutoMapper but am trying to update AutoMapper 4 to AutoMapper 10 (last version to support .Net Framework) on a project, and I have run into a problem: The ResolutionContext changed in the 4-5 upgrade so that it no longer has a Parent property.
The existing code works with an attribute that is put on properties in the view model where zero is supposed to be treated as a null, and the existing type converter has this code in it:
var prop = context.Parent.Parent.DestinationType.GetProperty(context.MemberName);
var attributes = prop.GetCustomAttributes(false);
var zeroAttr = attributes.Where(a => a.GetType() == typeof(ZAttribute)).ToList();
But as of AutoMapper 5, ResolutionContext.Parent and ResolutionContext.Member no longer exists.
This allows mapping zero to null for any/all view model, as long as the property has the attribute, there doesn't need to a specific mapping for that type (I think that is how it works). If the attribute isn’t on the property the normal mapping is done (zero stays zero).
How can this be done with AutoMapper 10?
I'm thinking it might be some type of ValueResolver...

AutoMapper inline mapping throwing mapper not initialized

I'm trying to use AutoMapper in a API wrapper class library project to map from API models to our domain models. While looking at the AutoMapper documentation I ran into the inline mapping feature.
Documentation says:
AutoMapper creates type maps on the fly (new in 6.2.0). When you call Mapper.Map for the first time, AutoMapper will create the type map configuration and compile the mapping plan. Subsequent mapping calls will use the compiled map.
So I wrote the following line of code in my wrapper class library:
var data = response.Results.Select(Mapper.Map<Session, Media>).ToList();
basically just trying to map the Session object I get from the API into our Media objects. But this throws the following error:
Mapper not initialized. Call Initialize with appropriate configuration. If you are trying to use mapper instances through a container or otherwise, make sure you do not have any calls to the static Mapper.Map methods, and if you're using ProjectTo or UseAsDataSource extension methods, make sure you pass in the appropriate IConfigurationProvider instance.
I was under the impression that inline mapping is exactly supposed to bypass having to initialize and define configuration for AutoMapper? Am I wrong?
Also if I am indeed wrong then how are you supposed to configure and initialize AutoMapper inside a class library to where it happens only once? I would like the library to be independent, meaning I don't want the programmer using the library to have to configure AutoMapper in his project in order for the library to work properly.

SearchDomainFactory.Instance is obsolete: 'Inject me!' ( Can't find out how to create instance)

I'm in the process of trying to migrate a R# extension project from R# 6 to R# 8. (I've taken over a project that someone wrote, and I'm new to writing extensions.)
In the existing v6 project there is a class that derives from RenameWorkflow, and the constructor used to look like this;
public class RenameStepWorkflow : RenameWorkflow
{
public RenameStepWorkflow(ISolution Solution, string ActionId)
: base(Solution, ActionId)
{
}
This used to work in R# SDK v 6, but now in V8, RenameWorkflow no longer has a constructor that takes Solution and actionId. The new constructor signature now looks like this;
public RenameWorkflow(
IShellLocks locks,
SearchDomainFactory searchDomainFactory,
RenameRefactoringService renameRefactoringService,
ISolution solution,
string actionId);
now heres my problem that I need help with (I think)
I've copied the constructor, and now the constructor of this class has to satisfy these new dependancies. Through some digging I've managed to find a way to satisfy all the dependencies, except for 'SearchDomainFactory'. The closest I can come to instantiating via the updated constructor is as follows;
new RenameStepWorkflow(Solution.Locks, JetBrains.ReSharper.Psi.Search.SearchDomainFactory.Instance, RenameRefactoringService.Instance, this.Solution, null)
All looks good, except that JetBrains.ReSharper.Psi.Search.SearchDomainFactory.Instance is marked as Obsolete, and gives me a compile error that I cannot work around, even using #pragma does not allow me to compile the code. The exact error message I get when I compile is Error 16 'JetBrains.ReSharper.Psi.Search.SearchDomainFactory.Instance' is obsolete: 'Inject me!'
Obvious next question..ok, how? How do I 'inject you'? I cannot find any documentation over this new breaking change, in fact, I cannot find any documentation (or sample projects) that even mentions DrivenRefactoringWorkflow or RenameWorkflow, (the classes that now require the new SearchDomainFactory), or any information on SearchDomainFactory.Instance suddenly now obsolete and how to satisfy the need to 'inject' it.
Any help would be most appreciated! Thank you,
regards
Alan
ReSharper has its own IoC container, which is responsible for creating instances of classes, and "injecting" dependencies as constructor parameters. Classes marked with attributes such as [ShellComponent] or [SolutionComponent] are handled by the container, created when the application starts or a solution is loaded, respectively.
Dependencies should be injected as constructor parameters, rather than using methods like GetComponent<TDependency> or static Instance properties, as this allows the container to control dependency lifetime, and ensure you're depending on appropriate components, and not creating leaks - a shell component cannot depend on a solution component for instance, it won't exist when the shell component is being created.
ReSharper introduced the IoC container a few releases ago, and a large proportion of the codebase has been updated to use it correctly, but there are a few hold-outs, where things are still done in a less than ideal manner - static Instance properties and calls to GetComponent. This is what you've encountered. You should be able to get an instance of SearchDomainFactory by putting it as a constructor parameter in your component.
You can find out more about the Component Model (the IoC container and related functionality) in the devguide: https://www.jetbrains.com/resharper/devguide/Platform/ComponentModel.html

Cannot find Html.Serialize helper in MVC 5 futures

I just installed MVC 5 futures in my solution using Package Manager, but I cannot find this helper method Html.Serialize, which was there in previous MVC Futures releases.
My Question: What namespace I need to include to start using Html.Serialize helper method with MVC 5 Futures?
Apparently, this extension helper is no longer included in the current MVC Futures.
In my case, I replaced the function call Html.Serialize by MvcSerializer.Serialize method which is included in Microsoft.Web.Mvc namespace.
To serialize any object in a hidden field:
#Html.Hidden("otherComplexData", new Microsoft.Web.Mvc.MvcSerializer().Serialize(complexObject))
Later, the controller can turn back the initial object:
[HttpPost]
public ActionResult Index(
IndexViewModel model,
[Deserialize] DataType otherComplexData
)
I hope you find it useful.

Accessing global variable in multithreaded Tomcat server

Edit: I've figured out the constructor for the singleton is getting called multiple times so it appears the classes are getting loaded more than once by separate class loaders. How can I make a global singleton in Tomcat? I've been googling, but no luck so far.
I have a singleton object that I construct like thus:
private static volatile KeyMapper mapper = null;
public static KeyMapper getMapper()
{
if(mapper == null)
{
synchronized(Utils.class)
{
if(mapper == null)
{
mapper = new LocalMemoryMapper();
}
}
}
return mapper;
}
The class KeyMapper is basically a synchronized wrapper to HashMap with only two functions, one to add a mapping and one to remove a mapping. When running in Tomcat 6.24 on my 32bit Windows machine everything works fine. However when running on a 64 bit Linux machine (CentOS 5.4 with OpenJDK 1.6.0-b09) I add one mapping and print out the size of the HashMap used by KeyMapper to verify the mapping got added (i.e. verify size = 1). Then I try to retrieve the mapping with another request and I keep getting null and when I checked the size of the HashMap it was 0. I'm confident the mapping isn't accidentally being removed since I've commented out all calls to remove (and I don't use clear or any other mutators, just get and put).
The requests are going through Tomcat 6.24 (configured to use 200 threads with a minimum of 4 threads) and I passed -Xnoclassgc to the jvm to ensure the class isn't inadvertently getting garbage collected (jvm is also running in -server mode). I also added a finalize method to KeyMapper to print to stderr if it ever gets garbage collected to verify that it wasn't being garbage collected.
I'm at my wits end and I can't figure out why one minute the entry in HashMap is there and the next it isn't :(
Another wild guess: is it possible the two requests are being served by different copies of your web app? Each would be in its own ClassLoader and thus have a different copy of the singleton.
Have you tried removing the outer check
if(mapper == null)
{
Thereby always hitting the Synchronized point, it's subtle stuff but possibly you're hitting the double-checked locking idiom problem. Described here and in many other articles.
Must admit I've never seen the problem actually bite someone before, but this sure sounds like it.
With this solution, the JVM guarantees that it's only one mapper and that's it's initialized before use.
public enum KeyMapperFactory {
;
private static KeyMapper mapper = new LocalMemoryMapper();
public static KeyMapper getMapper() {
return mapper;
}
}
This may not be the cause of your problem but you are using the faulty double-checked locking. See this,
http://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java
I found a rather poor fix. I exported my code as a JAR and put it in $TOMCAT/lib and that worked. This is clearly a class loader issue.
Edit: Figured out the solution
Ok, I finally figured out the problem.
I had made my application the default application for the server by adding a to server.xml and setting the path to "". However, when I was accessing it through the URL http://localhost/somepage.jsp for somethings, but also the URL http://localhost/appname/anotherpage.jsp for other things.
Once I changed all the URLs to use http://localhost/ instead of http://localhost/appname the problem was fixed.

Resources