Is AutoMapper expected to silently fail when mapping the same type without a map configured? - automapper

Consider the following:
public class Foo
{
public int Bar { get; set; }
}
[Test]
void Main()
{
var mapper = new MapperConfiguration(c => c.AddProfile<EmptyProfile>()).CreateMapper();
var foo = new Foo(){Bar = 1};
var baz = new Foo();
mapper.Map(foo, baz); // does not throw AutoMapperMappingException
Assert.AreEqual(foo.Bar, baz.Bar); // fails
}
Is this expected behavior using 10.0.0?

According to the maintainers, this is by design.
That's by design. But check
https://docs.automapper.org/en/latest/Configuration-validation.html#custom-validations.
from https://github.com/AutoMapper/AutoMapper/issues/3480

Related

#:generic only for some type parameters

If I want to create class with 2 type parameters, and I want specialized implementation for every first type parameter used, but I do not want it for second type parameter.
For example I want my own Map
#:generic #:remove
class MyMap {
public var map: Map<K, V> = new Map();
public function new() {}
}
This will generate implementation for every combination of K and V used. But I want different implementations for K only.
I've tried making abstract over #:generic class with needed type parameter, or extending such class. But this does not work. Both ways haxe compiler generates creation of MyMapBase class, and does not generate that class at all.
#:generic #:remove
class MyMapBase<K> {
public var map: Map<K, Dynamic> = new Map();
public function new() {}
}
class MyMap1<K, V> extends MyMapBase<K> {
}
abstract MyMap2<K, V>(MyMapBase<K>) {
public function new() {
this = new MyMapBase();
}
}
You don't need your own class at all. And since your values are stored as dynamic, you need only one instance of a map per key type. If that is not desired, you can change it back to instances per value, but then why to use dynamic values? Anyway, here is a map version which works across all targets.
#:multiType
abstract MyMap<K, V>(Map<K, Dynamic>) {
public function new();
public inline function set(k:K, v:V) this.set(k, v);
public inline function get(k:K) return this.get(k);
public static var string_map = new Map<String, Dynamic>();
#:to static inline function toStringMap<K:String>(t:Map<K, Dynamic>) {
return string_map;
}
public static var int_map = new Map<Int, Dynamic>();
#:to static inline function toIntMap<K:Int>(t:Map<K, Dynamic>) {
return int_map;
}
public static var object_map = new Map<{}, Dynamic>();
#:to static inline function toObjectMap<K:{}>(t:Map<K, Dynamic>) {
return object_map;
}
}
var i = new MyMap<String, Int>();
i.set("zero", 0);
trace(Type.getClassName(Type.getClass(i))); //haxe.ds.StringMap
trace(i); // {zero => 0}
var s = new MyMap<String, String>();
s.set("one", "1");
trace(Type.getClassName(Type.getClass(s))); //haxe.ds.StringMap
trace(s); // {zero => 0, one => 1}
// var v:Int = i.get("one") will fail on Java and HL
// we let v to infer as Null<Dynamic> instead
var v = i.get("one");
trace(v);
Here is my solution. I've used #:multiType abstract. This feature is not well documented in haxe, but one can look at Map implementation.
#:generic #:remove
class MyMapImpl<K> implements IMyMap<K, Dynamic> {
public var map: Map<K, Dynamic> = new Map();
public function new() {}
}
interface IMyMap<K, V> {
public var map: Map<K, V>;
}
#:multiType(K)
abstract MyMap<K, V>(IMyMap<K, V>) {
public function new();
public var map(get, never): Map<K, V>;
inline function get_map(): Map<K, V> {
return this.map;
}
#:to static inline function toStringMap<K:String, V>(t:IMyMap<K, V>):MyMapImpl<String> {
return cast new MyMapImpl<String>();
}
#:to static inline function toIntMap<K:Int, V>(t:IMyMap<K, V>):MyMapImpl<Int> {
return cast new MyMapImpl<Int>();
}
}
class Main {
static function main() {
var m = new MyMap<String, Int>();
trace(Type.getClassName(Type.getClass(m))); //MyMapImpl_String
trace(Type.getClassName(Type.getClass(m.map))); //haxe.ds.StringMap
var m = new MyMap<String, String>();
trace(Type.getClassName(Type.getClass(m))); //MyMapImpl_String
trace(Type.getClassName(Type.getClass(m.map))); //haxe.ds.StringMap
var m = new MyMap<Int, Int>();
trace(Type.getClassName(Type.getClass(m))); //MyMapImpl_Int
trace(Type.getClassName(Type.getClass(m.map))); //haxe.ds.IntMap
}
}

Automapper: map an anonymous/dynamic type

I need some help to map an anonymous object using Automapper. The goal is combine Product and Unity in a ProductDto (in which unity is a product's property).
Autommaper CreateMissingTypeMaps configuration is set to true.
My Classes:
public class Product
{
public int Id { get; set; }
}
public class Unity
{
public int Id { get; set; }
}
public class ProductDto
{
public int Id { get; set; }
public UnityDto Unity{ get; set; }
}
public class UnityDto
{
public int Id { get; set; }
}
Test Code
Product p = new Product() { Id = 1 };
Unity u = new Unity() { Id = 999 };
var a = new { Product = p, Unity = u };
var t1 = Mapper.Map<ProductDto>(a.Product);
var t2 = Mapper.Map<UnityDto>(a.Unity);
var t3 = Mapper.Map<ProductDto>(a);
Console.WriteLine(string.Format("ProductId: {0}", t1.Id)); // Print 1
Console.WriteLine(string.Format("UnityId: {0}", t2.Id)); // Print 999
Console.WriteLine(string.Format("Anonymous ProductId: {0}", t3.Id)); // Print 0 <<< ERROR: It should be 1 >>>
Console.WriteLine(string.Format("Anonymous UnityId: {0}", t3.Unity.Id)); // Print 999
There are two maps added to the profile:
CreateMap<Product, ProductDto>();
CreateMap<Unity, UnityDto>();
The problem is how Automapper map anonymous objects. I haven't time to check out Automapper source code but I got the desired behaviour with minor changes on my anonymous object:
var a = new { Id = p.Id, Unity = u };
By doing this, I might even delete previous mappings because now it is using only CreateMissingTypeMaps.
Note: As matter of fact I'm not sure if it is really an issue or I it was just my unreal expectations.

ServiceStack 4 licensing

I have the following code:
class Program
{
static void Main(string[] args)
{
var clientManager = new BasicRedisClientManager("127.0.0.1:6379");
var person = new Person {Name = "Maria"};
using (var redis = clientManager.GetClient())
{
var redisPerson = redis.As<Person>();
redis.StoreAsHash(redisPerson);
}
}
}
public class Person
{
public string Name { get; set; }
}
}
and get the error "The free-quota limit on '20 ServiceStack.Text Types' has been reached...."
Excuse me ... where are the 20 ServiceStack.Text Types? Am I missing something?
Thanks
The issue is that redis.As<Person>() returns an entire Generic Redis Client that's typed to the Person entity which is clearer if you remove Type Inference for redisPerson:
IRedisTypedClient<Person> redisPerson = redis.As<Person>();
redis.StoreAsHash(redisPerson);
So this code attempts the improper usage of trying to serialize and save an entire Typed Redis Client using an untyped RedisClient which is not what you want to do, instead you should use the typed redisPerson Redis Client to save Person entities, here's a proper example of your program:
class Program
{
static void Main(string[] args)
{
var clientManager = new BasicRedisClientManager("127.0.0.1:6379");
var person = new Person { Id = 1, Name = "Maria" };
using (var redis = clientManager.GetClient())
{
var redisPerson = redis.As<Person>();
redisPerson.StoreAsHash(person);
var fromRedis = redisPerson.GetFromHash(person.Id);
fromRedis.PrintDump();
}
Console.ReadLine();
}
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
Which outputs:
{
Id: 1,
Name: Maria
}
Also note that most Typed API's require each Entity to have an Id primary key which is used to create the key the entity is stored at. See this answer for more info on how complex types are stored in ServiceStack.Redis.

Unable to cast object of type X to Y

I keep getting the exception “Unable to cast object of type X to Y” in some code. I’ve got an interface and two classes that implement it and it keeps throwing this error when casting from one to the other. The two classes and interface are in the same namespace in the same assembly so that’s not the issue. I created an isolated console application to figure this mess out but I can’t get them to cast to one another. I think I’ve forgotten some basic .Net rule here. Anything look off in this code to you?
My isolated app code:
class Program
{
static void Main(string[] args)
{
RecurringPaymentResult r = new RecurringPaymentResult();
r.AddError("test");
ProcessPaymentResult p = null;
p = (ProcessPaymentResult)r; // Doesn't compile. "Cannot convert type RecurringPaymentResult to ProcessPaymentResult"
p = (IPaymentResult)r; // Doesn't compile. "Cannot convert type RecurringPaymentResult to ProcessPaymentResult. An explicit conversion exists (are you missing a cast?)"
p = (ProcessPaymentResult)((IPaymentResult)r); // Compiles but throws: "Unable to cast object of type RecurringPaymentResult to ProcessPaymentResult" during runtime
}
}
My core code:
public interface IPaymentResult
{
IList<string> Errors { get; set; }
bool Success { get; }
void AddError(string error);
}
public partial class RecurringPaymentResult : IPaymentResult
{
public IList<string> Errors { get; set; }
public RecurringPaymentResult()
{
this.Errors = new List<string>();
}
public bool Success
{
get { return (this.Errors.Count == 0); }
}
public void AddError(string error)
{
this.Errors.Add(error);
}
}
public partial class ProcessPaymentResult : IPaymentResult
{
private PaymentStatus _newPaymentStatus = PaymentStatus.Pending;
public IList<string> Errors { get; set; }
public ProcessPaymentResult()
{
this.Errors = new List<string>();
}
public bool Success
{
get { return (this.Errors.Count == 0); }
}
public void AddError(string error)
{
this.Errors.Add(error);
}
// More properties and methods here…
}
One major mistake I see in your code is saying "p =".
You have already decided the type of p and you are assigning various other variables in this type which is wrong.
Below are all possible conversions available :
RecurringPaymentResult r = new RecurringPaymentResult();
r.AddError("test");
ProcessPaymentResult p = null;
var r1 = (IPaymentResult)r; //type of r1 becomes IPaymentResult
var r2 = (IPaymentResult)p; //type of r2 becomes IPaymentResult
var r3 = (RecurringPaymentResult)r1; //type of r3 becomes RecurringPaymentResult
var r4 = (ProcessPaymentResult)r2; //type of r4 becomes ProcessPaymentResult
Logical explaination:
Man (class) has Eye(interface) and Elephant(class) has Eye(interface). Interface provides See method(). Both Man and Deer implements Eye interface by having See method in them.
Now, What you are trying is converting Man object into Elephant object which is not possible as space to store those objects have different requirements.

Initializing Nested strongly typed objects in LINQ to Entities

Consider this Example
public class FooWrapper
{
public FooWrapper() { }
public Foo FooObject { get; set; }
public Bar BarObject { get; set; }
}
public IEnumerable<FooWrapper> ListFoosWithBars(int userID)
{
IEnumerable<Bar> tempBar = ListBarsByUserID(userID);
IEnumerable<FooWrapper> results = (
from f in _entities.FooSet
join b in tempBar on f.ID equals b.foos.ID
select new FooWrapper
{
FooObject = f,
BarObject = b
});
return results;
}
what if my Foo type class has Properties like
public class Foo(){
FProperty1{get; set;}
FPorperty2{get; set;}
}
public class Bar(){
BProperty1{get; set;}
BProperty2{get; set;}
}
and now i want to initialize my object in query like this
select new FooWrapper
{
FooObject.FProperty1 = f,
BarObject.BProperty2 = b
});
can I do this?
How will this work?
What you want is:
select new FooWrapper
{
FooObject = new Foo { FProperty1 = f },
BarObject = new Bar { BProperty2 = b }
});

Resources