[C#] Tipi di coercizione in diversi spazi dei nomi con layout identico in C #


Answers

Quindi ecco come ho implementato gli operatori di conversione impliciti usando la riflessione. SvcUtil crea classi parziali quindi ho aggiunto un operatore di conversione implicito per ogni direzione della conversione, quindi nel codice del client è possibile digitare Type1 = Type2 .

In questo frammento WebAuthenticationCredentials è una proprietà di WebAuthenticationDetails così, mentre itera le proprietà dell'oggetto sorgente se i tipi non sono gli stessi (built-in), controlla il nome dei tipi (senza lo spazio dei nomi) e ricorsivamente chiama la funzione di copia con quelle proprietà .

internal class ReflectionCopy
{
    public static ToType Copy<ToType>(object from) where ToType : new()
    {
        return (ToType)Copy(typeof(ToType), from);
    }

    public static object Copy(Type totype, object from)
    {
        object to = Activator.CreateInstance(totype);

        PropertyInfo[] tpis = totype.GetProperties(BindingFlags.Public | BindingFlags.Instance);
        PropertyInfo[] fpis = from.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

        // Go through each property on the "to" object
        Array.ForEach(tpis, tpi =>
        {
            // Find a matching property by name on the "from" object
            PropertyInfo fpi = Array.Find(fpis, pi => pi.Name == tpi.Name);
            if (fpi != null)
            {
                // Do the source and destination have identical types (built-ins)?
                if (fpi.PropertyType == tpi.PropertyType)
                {
                    // Transfer the value
                    tpi.SetValue(to, fpi.GetValue(from, null), null);
                }
                else
                {
                    // If type names are the same (ignoring namespace) copy them recursively
                    if (fpi.PropertyType.Name == tpi.PropertyType.Name)
                        tpi.SetValue(to, Copy(fpi.PropertyType, tpi.GetValue(from, null)), null);
                }
            }
        });

        return to;
    }
}

namespace Rate
{
    partial class WebAuthenticationDetail
    {
        public static implicit operator Ship.WebAuthenticationDetail(WebAuthenticationDetail from)
        {
            return ReflectionCopy.Copy<Ship.WebAuthenticationDetail>(from);
        }
    }

    partial class WebAuthenticationCredential
    {
        public static implicit operator Ship.WebAuthenticationCredential(WebAuthenticationCredential from)
        {
            return ReflectionCopy.Copy<Ship.WebAuthenticationCredential>(from);
        }
    }
}

namespace Ship
{
    partial class WebAuthenticationDetail
    {
        public static implicit operator Rate.WebAuthenticationDetail(WebAuthenticationDetail from)
        {
            return ReflectionCopy.Copy<Rate.WebAuthenticationDetail>(from);
        }
    }

    partial class WebAuthenticationCredential
    {
        public static implicit operator Rate.WebAuthenticationCredential(WebAuthenticationCredential from)
        {
            return ReflectionCopy.Copy<Rate.WebAuthenticationCredential>(from);
        }
    }
}
Question

Ho iniziato a scrivere un'interfaccia per le API del servizio web di FedEx. Hanno 3 diverse API a cui sono interessato; Valuta, spedisci e traccia. Sto generando i proxy di servizio con SvcUtil.exe.

I diversi endpoint di servizio sono specificati da FedEx nei propri file WSDL. Ogni endpoint del servizio ha il proprio spazio dei nomi xml (ad esempio http://fedex.com/ws/rate/v5 e http://fedex.com/ws/ship/v5 )

Gli endpoint del servizio utilizzano alcuni tipi identici come Indirizzo, Misure, Peso, AuthenticationDetail, ClientDetail, ecc ...

E qui è dove si trova il problema, posso fornire tutti i file WSDL contemporaneamente a SvcUtil.exe e normalmente convergerebbe tutti i tipi identici in un singolo tipo condiviso, ma poiché ciascuno dei servizi di FedEx si trova nel proprio spazio dei nomi, e essi redeclare questi tipi in ogni file WSDL sotto quello spazio dei nomi, invece, si tratta di un indirizzo, indirizzo1 e indirizzo2 uno per ogni spazio dei nomi.

Per risolvere questo problema, quello che faccio ora è eseguire separatamente ogni WSDL tramite svcutil e inserirli ciascuno nel proprio namespace .NET (ad es. FedEx.Rate, FedEx.Ship, FedEx.Track). Il problema con questo è che ora ho un tipo di indirizzo distinto in ogni spazio dei nomi (FedEx.Rate.Address, FedEx.Ship.Address).

Ciò rende difficile generalizzare il codice utilizzato tra i servizi come un metodo factory GetAuthenticationDetail () in modo da non dover ripetere quel codice in ogni luogo in cui utilizzo i diversi servizi.

C'è un modo in C # per forzare FedEx.Rate.Address a FedEx.Ship.Address?




Le classi generate sono definite come "parziali"? In tal caso, è possibile estenderli in un file diverso ed estrarre un'interfaccia e lasciarla implementare da tutte le classi Address.




Links