Domanda

UPDATE: questa roba è evoluto in un bel progetto, vede a http: // valueinjecter.codeplex.com


check this out, ho appena scritto un semplice automapper, prende il valore dalla proprietà con lo stesso nome e il tipo di un oggetto e la mette in un altro, ed è possibile aggiungere eccezioni (IFS, switch) per ogni tipo potrebbe essere necessario < br>

quindi dimmi cosa ne pensi a riguardo?

L'ho fatto così ho potuto fare qualcosa di simile:

Product –> ProductDTO

ProductDTO –> Product

è così che iniziata:

utilizzare il tipo di "oggetto" nei miei Ingressi / Dto / ViewModels per DropDowns perché io mando il codice html di un IEnumerable e ricevo un array di stringhe di chiavi selezionate di nuovo

 public void Map(object a, object b)
    {
        var pp = a.GetType().GetProperties();
        foreach (var pa in pp)
        {
            var value = pa.GetValue(a, null);

            // property with the same name in b
            var pb = b.GetType().GetProperty(pa.Name);
            if (pb == null)
            {
                //no such property in b
                continue;
            }

            if (pa.PropertyType == pb.PropertyType)
            {
                pb.SetValue(b, value, null);
            }

        }
    }

UPDATE: il vero utilizzo:
i metodi di build (ingresso = Dto):

        public static TI BuildInput<TI, T>(this T entity) where TI: class, new()
        {
            var input = new TI();
            input = Map(entity, input) as TI;
            return input;
        }

        public static T BuildEntity<T, TI, TR>(this TI input)
            where T : class, new()
            where TR : IBaseAdvanceService<T>
        {               
            var id = (long)input.GetType().GetProperty("Id").GetValue(input, null);
            var entity = LocatorConfigurator.Resolve<TR>().Get(id) ?? new T();
            entity = Map(input, entity) as T;
            return entity;
        }

        public static TI RebuildInput<T, TI, TR>(this TI input)
            where T: class, new()
            where TR : IBaseAdvanceService<T>
            where TI : class, new()
        {

                return input.BuildEntity<T, TI, TR>().BuildInput<TI, T>();
            }

nel controller:

    public ActionResult Create()
    { 
        return View(new Organisation().BuildInput<OrganisationInput, Organisation>());
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create(OrganisationInput o)
    {
        if (!ModelState.IsValid)
        {
            return View(o.RebuildInput<Organisation,OrganisationInput, IOrganisationService>());                
        }
        organisationService.SaveOrUpdate(o.BuildEntity<Organisation, OrganisationInput, IOrganisationService>());
        return RedirectToAction("Index");
    }

Il metodo vera mappa

public static object Map(object a, object b)
        {
            var lookups = GetLookups();

            var propertyInfos = a.GetType().GetProperties();
            foreach (var pa in propertyInfos)
            {
                var value = pa.GetValue(a, null);

                // property with the same name in b
                var pb = b.GetType().GetProperty(pa.Name);
                if (pb == null)
                {
                    continue;
                }

                if (pa.PropertyType == pb.PropertyType)
                {
                    pb.SetValue(b, value, null);
                }
                else if (lookups.Contains(pa.Name) && pa.PropertyType == typeof(LookupItem))
                {
                    pb.SetValue(b, (pa.GetValue(a, null) as LookupItem).GetSelectList(pa.Name), null);
                }
                else if (lookups.Contains(pa.Name) && pa.PropertyType == typeof(object))
                {
                    pb.SetValue(b, pa.GetValue(a, null).ReadSelectItemValue(), null);
                }
                else if (pa.PropertyType == typeof(long) && pb.PropertyType == typeof(Organisation))
                {
                    pb.SetValue(b, pa.GetValue<long>(a).ReadOrganisationId(), null);
                }
                else if (pa.PropertyType == typeof(Organisation) && pb.PropertyType == typeof(long))
                {
                    pb.SetValue(b, pa.GetValue<Organisation>(a).Id, null);
                }
            }

            return b;
        }
È stato utile?

Soluzione

Una cosa che si potrebbe desiderare di aggiungere è quello di memorizzare nella cache i bit di riflessione. Se si associa un oggetto due volte, probabilmente non si desidera cercare tutte le cose riflessione di nuovo. Inoltre, le cose come GetValue e SetValue sono piuttosto lento, sono passato ai delegati tardiva + Reflection.Emit per accelerare le cose.

Altri suggerimenti

Basta usare automapper . Questo va bene, ma sarà crescere in un mini progetto.

solo alcune cose AM (quello vero) fa è:

  • segnalazione se si dispone di proprietà che non può essere mappato
  • appiattimento oggetti
  • fornendo ganci di personalizzare alcuni aspetti, non in una grande dichiarazione interruttore
  • utilizzando Expression.Compile per motivi di Potenza, piuttosto che di riflessione direttamente

Ma è certamente uno spazio interessante per pasticciare in, e l'idea di mappatura automatica è sicuramente utile.

Un po 'come in DI 15 o noreferrer 33 linee vs Ninject o dai suoi amici -?. fresco, ma perché

Io lo prendo che hai letto il articolo e commenti riguardo la mappatura 2 modo su Jimmy blog ?

Solo un pensiero:

Ci si potrebbe chiedere quale sia il punto di un'astrazione è se l'astrazione è così facilmente mappato a quello che è astratto.

  

è possibile aggiungere eccezioni (IFS, switch)   per ogni tipo potrebbe essere necessario

Non hai intenzione di fare questo. Sul serio. istruzioni case che agiscono per tipi di oggetti sono cattivo stile OOP. Voglio dire, davvero male. Come guidare con un drink di vodka all'interno del vostro stomaco. Si può lavorare per qualche tempo, ma alla fine si ottiene nei guai.

OK Jimmy ti ha detto di non usare automapper ... ma scommetto che voleva dire qualcos'altro. Ora, avete inventato qualcosa di diverso - qualcosa che rendono Jimmy felice? ;-) No, hai appena fatto il proprio mezzo laminati automapper. E Jimmy ti ha detto di non usarlo! ; -)

Quindi, ecco il mio suggerimento: ignorare quello che dice Jimmy, basti pensare se stessi .. e utilizzare automapper; -)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top