ppittle / pMixins

pMixins - Mixin framework for C#
http://pMixins.com
Apache License 2.0
23 stars 5 forks source link

Define recipe for structural typing(auto mapping) if possible #40

Closed dzmitry-lahoda closed 9 years ago

dzmitry-lahoda commented 9 years ago

Given class

public  Described{
  public string DisplayName {get;}
  public string Description {get;}
}

and

public partial class View{
  public void Show(Described a)
{
  Console.WriteLine(a.DisplayName +" : " + a.Description");
}
}

Given there is other class from third party

public  MyDescribed{
  public string DisplayName {get;}
  public string Description {get;}
}

generate

public partial class ViewExtentions{
  public void Show(MyDescribed a)
{
  Console.WriteLine(a.DisplayName +" : " + a.Description");
}
}

if and only if MyDescribed has all methods of Described.

  1. Allows to write less wrappers.
  2. Allows less usage of runtime auto mappers.

Alternatively:

  1. generate wrapper object class MyDescribedWrap(MyDescribed a):Described with implicit conversions
  2. use interface as structural type.
ppittle commented 9 years ago

Hi asd-and-Rizzo,

pMixins is not intended to map data between similar objects, so I'm not sure this is a good fit. pMixins promotes code reuse via Compostion, ie by creating the wrapper code for you.

So working loosely from your code example, if you had multiple classes that needed to implement Show(Described a), you could use pMixins to allow you to inject that member into your classes:

public class ShowImplementation{
    public void Show(Described a)
    {
        Console.WriteLine(a.DisplayName +" : " + a.Description");
     }
}

[pMixin(Target=typeof(ShowImplementation)]
public partial class A{}

[pMixin(Target=typeof(ShowImplementation)]
public partial class B{}

Both class A and B will now have the method Show:

new A().Show(new Described());
new B().Show(new Described());

It's important to note, however, that pMixins isn't copying Show's member body (the Console.WriteLine statement into class A and B and isn't performing any mapping. It's only wrapping a call to ShowImplementation.Show

Basically, the code behind file is doing this:

public partial class A{
    public void Show(Described a){
         new ShowImplemntation().Show(a);
    }
}

If you are looking to map MyDescribed to Described there are alternative projects that focus specifically on this project. Jimmy Bogard's AutoMapper is a good one and is on GitHub here: https://github.com/AutoMapper/AutoMapper

dzmitry-lahoda commented 9 years ago

Thanks for clarification. I have next points to clarify what I meant: 1.There is third party Other.dll with OtherDescribed class. So I want to generate code for this OtherDescribed if it fits Described defined in my code. And case was to avoid wrapper to avoid GC pressure to create wrapper for each such 3rd party object.

It may then compose with matching like this:

ViewExtentions.Show(Object o)
{
   var p = o as OtherDescrived();
   if (p!=null) ViewExtentions.Show(p);
   var m = o as  MyDescribed();
   if (m!=null) ViewExtentions.Show(m);
}

2.Runtime automappers good to avoid. Reasons: if need devices support(iOS,CF), if need performance, if need compile time errors. So next on code level generation is good:

class OtherDescribedWrap(OtherDescribed a):Described{}//OtherDescribed  from 3rd party dll
var l = new List<Described>{new MyDescribed(),new OtherDescribedWrap(new OtherDescribed())
control.ItemsSource = l;

This is decorator delegation based composition plus generic container composition I think.

3.[pMixin(Target=typeof(ShowImplementation)] precludes composition on 3rd party code.

But most of code with which I do composition is 3rd party (even if developed in single organization or even in single team, or when approaches like "effortless modularity"-split 80% as OS projects).

Leading to severe limitation of pMixin usage in real world. While I believe that future with tools like NRefacoty and Roslyn is of creating some DSL which will allow define and generate different code pieces (because C# will not support this in nearest or ever future inside itself).