Skip to content

How it works?

Rafael Lillo edited this page Mar 5, 2020 · 4 revisions

Cast form don't reflection to map one object to another instance of we create a object to mapper at startup.

Same type

public class Foo
{
    public int Id { get; set; }
    public string Text { get; set; }
}

public class Bar
{
    public int Id { get; set; }
    public string Text { get; set; }
}

public class MapFooToBar : IMap<Foo, Bar>
{
   public Bar Map(Foo source)
   {
      return new Bar 
      {
         Id = source.Id,
         Text = source.Text
      }
   }
}

Different type

public class Foo
{
    public int Id { get; set; }
}

public class Bar
{
    public long Id { get; set; }
}

public class MapFooToBar : IMap<Foo, Bar>
{
   public Bar Map(Foo source)
   {
      return new Bar 
      {
         Id = Convert.ToInt64(source.Id)
      }
   }
}

With Nullable Type

Souce nullable and destiny not:

public class Foo
{
    public int? Id { get; set; }
}

public class Bar
{
    public int Id { get; set; }
}

public class MapFooToBar : IMap<Foo, Bar>
{
   public Bar Map(Foo source)
   {
      return new Bar 
      {
         Id = source.Id ?? 0
      }
   }
}

Souce not nullable and destiny nullable

public class Foo
{
    public int Id { get; set; }
}

public class Bar
{
    public int? Id { get; set; }
}

public class MapFooToBar : IMap<Foo, Bar>
{
   public Bar Map(Foo source)
   {
      return new Bar 
      {
         Id = source.Id
      }
   }
}

Both nullable and different type

public class Foo
{
    public int Id { get; set; }
}

public class Bar
{
    public long? Id { get; set; }
}

public class MapFooToBar : IMap<Foo, Bar>
{
   public Bar Map(Foo source)
   {
      return new Bar 
      {
         Id = source.Id.HasValue ? new long?(source.Id.Value) : null
      }
   }
}

For different type but without circular reference

public class Foo
{
    public int Id { get; set; }
    public string Text { get; set; }
    public SimpleB Simple { get; set; }
}

public class SimpleA
{
    public int Number { get; set; }
    public string Value { get; set; }
}

public class Bar
{
    public int Id { get; set; }
    public string Text { get; set; }
    public SimpleB Simple { get; set; }
}

public class SimpleB
{
    public int Number { get; set; }
    public string Value { get; set; }
}

public class MapFooToBar : IMap<Foo, Bar>
{
   private readonly IServiceProvider _provider;
   private IMap<SimpleA, SimpleB> _mapSimpleAToSimpleB;
   private bool _isInit = false;

   public MapFooToBar(IServiceProvider provider)
   {
      _provider = provider;
   }

   private void Init()
   {
      if(!_init)
      {
         _mapSimpleAToSimpleB = (IMap<SimpleA, SimpleB>)_provider.GetService(typeof(IMap<SimpleA, SimpleB>));
         _init = true;
      }
   }

   public Bar Map(Foo source)
   {
      Init();
      return new Bar 
      {
         Id = source.Id,
         Text = source.Text,
         Simple = _mapSimpleAToSimpleB.Map(source.Simple)
      }
   }
}

For different type but with circular reference

public class Foo
{
    public int Id { get; set; }
    public string Text { get; set; }
    public Bar Barr { get; set; }
}

public class Bar
{
    public int Id { get; set; }
    public string Text { get; set; }
    public Foo Foo { get; set; }
}

public class MapFooToBar : IMap<Foo, Bar>
{
   private readonly IServiceProvider _provider;
   private readonly Counter _counter;
   private IMap<Bar, Foo> _mapBarToFoo;
   private bool _isInit = false;

   public MapFooToBar(IServiceProvider provider)
   {
      _provider = provider;
   }

   private void Init()
   {
      if(!_init)
      {
         _mapBarToFoo = (IMap<Bar, Foo>)_provider.GetService(typeof(IMap<Bar, Foo>));
         _counter = (Counter)_provider.GetService(typeof(Counter));
         _init = true;
      }
   }

   public Bar Map(Foo source)
   {
      Init();
      return new Bar 
      {
         Id = source.Id,
         Text = source.Text,
         Foo = source != null && _counter.GetCounter(source) < 3 ? _mapBarToFoo.Map(source.Bar) : null
      }3
   }
}