public FourSquareLoadRequest(LoadContext context, JeffWilcox.FourthAndMayor.FourSquareWebClient.UriErrorPair uri, string postData) : this(context, uri) { Debug.Assert(_sr != null); _sr.PostString = postData; }
/// <summary> /// Create a WebLoadRequest /// </summary> /// <param name="loadContext"></param> /// <param name="uri">The URI to request</param> /// <param name="method">The method to request - GET or POST</param> /// <param name="data">The data for a POST request</param> /// <param name="supportEtags"></param> public WebLoadRequest(LoadContext loadContext, Uri uri, string method, string data, bool supportEtags) : this(loadContext, uri) { Method = method; Data = data; SupportEtags = supportEtags; }
public override object Deserialize(LoadContext context, Type objectType, System.IO.Stream stream) { DateTime start = DateTime.Now; XElement xElement = XElement.Load(stream); Debug.Assert(xElement.Name == "rsp", "XML root is not rsp"); // check success/fail. // var stat = xElement.Attribute("stat").Value; if (stat != "ok") { var err = xElement.Element("err"); var msg = err.Attribute("msg").Value; PriorityQueue.AddUiWorkItem(() => { MessageBox.Show(String.Format("Error making call {0}: {1}", "getInfo", msg)); }); } else { return DeserializeCore(context, (XElement)xElement.FirstNode, objectType, stream); } return null; }
/// <summary> /// Create a WebLoadRequest /// </summary> /// <param name="loadContext"></param> /// <param name="uri"></param> /// <param name="supportEtags"></param> public WebLoadRequest(LoadContext loadContext, Uri uri, bool supportEtags) : base(loadContext) { Uri = uri; Method = "GET"; SupportEtags = supportEtags; }
public FourSquareLoadRequest(LoadContext context, JeffWilcox.FourthAndMayor.FourSquareWebClient.UriErrorPair uri, byte[] postData, Dictionary<string, string> parameters) : this(context, uri) { Debug.Assert(_sr != null); _sr.PostBytes = postData; _sr.PostParameters = parameters; }
public override LoadRequest GetLoadRequest(LoadContext context, Type objectType) { return BuildRequest( context, "flickr.people.findByUsername", new FlickrArgument("username", (string)context.Identity) ); }
public override LoadRequest GetLoadRequest(LoadContext context, Type objectType) { return BuildRequest( context, "flickr.photosets.getList", new FlickrArgument[]{ new FlickrArgument("user_id", context.Identity.ToString()) }); }
/// <summary> /// Ctor. /// </summary> /// <param name="objectType">The type of the object being loaded</param> /// <param name="loadContext">The LoadContext for the load.</param> /// <param name="innerException">The original exception which caused the failure.</param> public LoadRequestFailedException(Type objectType, LoadContext loadContext, Exception innerException) : base("An error occurred loading an object of type " + objectType.Name + ", see InnerException for details.", innerException) { if (objectType == null) throw new ArgumentNullException(); if (loadContext == null) throw new ArgumentNullException(); ObjectType = objectType; LoadContext = loadContext; }
/// <summary> /// Set the given item's cache state to expired so that it will be re-fetched on the next request. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="loadContext"></param> public void Invalidate <T>(LoadContext loadContext) where T : new() { var cacheItem = Get <T>(loadContext, null, null, false); if (cacheItem != null) { cacheItem.SetForRefresh(); } }
/// <summary> /// Equals. /// </summary> /// <param name="obj"></param> /// <returns></returns> public override bool Equals(object obj) { LoadContext other = obj as LoadContext; if (other == null) { return(false); } return(Object.Equals(UniqueKey, other.UniqueKey)); }
/// <summary> /// Clear any stored state for the specified item, both from memory /// as well as from the store. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="id"></param> public void Clear <T>(LoadContext id) where T : new() { CacheEntry value; lock (_objectCache) { if (_objectCache.ContainsKey(typeof(T)) && _objectCache[typeof(T)].TryGetValue(id.UniqueKey, out value)) { value.Clear(); _objectCache[typeof(T)].Remove(id.UniqueKey); StoreProvider.DeleteAll(id.UniqueKey); } } }
/// <summary> /// Updates the live value from an inentional DataManager.Save operation. /// </summary> /// <param name="instance"></param> /// <param name="loadContext"></param> internal void UpdateValue(object instance, LoadContext loadContext) { UpdateExpiration(DateTime.Now, instance as ICachedItem); LoadContext = loadContext; if (_valueReference != null && _valueReference.IsAlive) { UpdateFrom(null, instance); } else { ValueInternal = instance; } }
/// <summary> /// Ctor. /// </summary> /// <param name="objectType">The type of the object being loaded</param> /// <param name="loadContext">The LoadContext for the load.</param> /// <param name="innerException">The original exception which caused the failure.</param> public LoadRequestFailedException(Type objectType, LoadContext loadContext, Exception innerException) : base("An error occurred loading an object of type " + objectType.Name + ", see InnerException for details.", innerException) { if (objectType == null) { throw new ArgumentNullException(); } if (loadContext == null) { throw new ArgumentNullException(); } ObjectType = objectType; LoadContext = loadContext; }
public FourSquareLoadRequest(LoadContext context, JeffWilcox.FourthAndMayor.FourSquareWebClient.UriErrorPair uri) : base(context) { if (_sr == null) { _sr = new FourSquareServiceRequest(); } _sr.Uri = uri.Uri; _sr.UseCredentials = null; if (uri.Error != null) { _error = uri.Error; } }
private IEnumerable <ProxyEntry> GetProxies <T>(LoadContext lc) { List <ProxyEntry> proxyList; if (!_proxies.TryGetValue(lc, out proxyList)) { return(new ProxyEntry[0]); } var proxies = from p in proxyList where p.ObjectType.IsAssignableFrom(typeof(T)) && p.ProxyReference.IsAlive select p; return(proxies.ToArray()); }
protected override object DeserializeCore(LoadContext context, System.Xml.Linq.XElement xml, Type objectType, System.IO.Stream stream) { //<user nsid="12037949632@N01"> // <username>Stewart</username> //</user> bool s; string nsid = TryGetValue(xml, "nsid", null, out s); if (s) { var dl = new UserNameVm((string)context.Identity); dl.UserId = nsid; return dl; } return null; }
public static object Deserialize(object dataLoader, LoadContext loadContext, Type objectType, Stream stream) { Type dataLoaderType = dataLoader.GetType(); MethodInfo mi; if (!_deserializeCache.TryGetValue(dataLoaderType, out mi)) { mi = FindMethodWorker(dataLoaderType, "Deserialize", typeof(DataLoaderProxy), typeof(Type), typeof(Stream)); _deserializeCache[dataLoaderType] = mi; } try { return(mi.Invoke(dataLoader, new object[] { loadContext, objectType, stream })); } catch (TargetInvocationException t) { throw t.InnerException; } }
public static object Deserialize(object dataLoader, LoadContext loadContext, Type objectType, Stream stream) { Type dataLoaderType = dataLoader.GetType(); MethodInfo mi; if (!_deserializeCache.TryGetValue(dataLoaderType, out mi)) { mi = FindMethodWorker(dataLoaderType, "Deserialize", typeof(DataLoaderProxy), typeof(Type), typeof(Stream)); _deserializeCache[dataLoaderType] = mi; } try { return mi.Invoke(dataLoader, new object[] { loadContext, objectType, stream }); } catch (TargetInvocationException t) { throw t.InnerException; } }
/// <summary> /// Set up all the handlers for this CacheEntry /// </summary> /// <param name="objectType"></param> /// <param name="context"></param> /// <param name="proxyCallback">callback that should be invoked when update is finished</param> public CacheEntry(LoadContext context, Type objectType, Action <CacheEntry> proxyCallback) { _proxyComplitionCallback = proxyCallback; LoadContext = context; ObjectType = objectType; _stats = new EntryStats(this); // set up our value loaders. // _cacheLoader = new CacheValueLoader(this); _cacheLoader.Loading += ValueLoader_Loading; _cacheLoader.ValueAvailable += Cached_ValueAvailable; _cacheLoader.LoadFailed += CacheLoader_Failed; _liveLoader = new LiveValueLoader(this); _liveLoader.Loading += ValueLoader_Loading; _liveLoader.ValueAvailable += Live_ValueAvailable; _liveLoader.LoadFailed += LiveValueLoader_Failed; NextCompletedAction = new UpdateCompletionHandler(this); }
public static LoadRequest GetLoadRequest(object dataLoader, LoadContext loadContext, Type objectType) { // look for the GetLoadRequestMethod. // Type dataLoaderType = dataLoader.GetType(); MethodInfo mi; if (!_getLoadRequestCache.TryGetValue(dataLoaderType, out mi)) { mi = FindMethodWorker(dataLoaderType, "GetLoadRequest", typeof(DataLoaderProxy), typeof(Type)); _getLoadRequestCache[dataLoaderType] = mi; } try { return((LoadRequest)mi.Invoke(dataLoader, new object[] { loadContext, objectType })); } catch (TargetInvocationException t) { throw t.InnerException; } }
/// <summary> /// Set up all the handlers for this CacheEntry /// </summary> /// <param name="objectType"></param> /// <param name="context"></param> /// <param name="proxyCallback">callback that should be invoked when update is finished</param> public CacheEntry(LoadContext context, Type objectType, Action<CacheEntry> proxyCallback) { _proxyComplitionCallback = proxyCallback; LoadContext = context; ObjectType = objectType; _stats = new EntryStats(this); // set up our value loaders. // _cacheLoader = new CacheValueLoader(this); _cacheLoader.Loading += ValueLoader_Loading; _cacheLoader.ValueAvailable += Cached_ValueAvailable; _cacheLoader.LoadFailed += CacheLoader_Failed; _liveLoader = new LiveValueLoader(this); _liveLoader.Loading += ValueLoader_Loading; _liveLoader.ValueAvailable += Live_ValueAvailable; _liveLoader.LoadFailed += LiveValueLoader_Failed; NextCompletedAction = new UpdateCompletionHandler(this); }
public static LoadRequest GetLoadRequest(object dataLoader, LoadContext loadContext, Type objectType) { // look for the GetLoadRequestMethod. // Type dataLoaderType = dataLoader.GetType(); MethodInfo mi; if (!_getLoadRequestCache.TryGetValue(dataLoaderType, out mi)) { mi = FindMethodWorker(dataLoaderType, "GetLoadRequest", typeof(DataLoaderProxy), typeof(Type)); _getLoadRequestCache[dataLoaderType] = mi; } try { return (LoadRequest)mi.Invoke(dataLoader, new object[] { loadContext, objectType }); } catch (TargetInvocationException t) { throw t.InnerException; } }
/// <summary> /// Saves data an instance into the cache. The DataLoader for type T must /// implement IDataOptimizer for this to work, othwerise an InvalidOperationException will be thrown. /// /// This also updates the current value in the cache and increments the update/cache time. In other words, /// this simulates a live load/refresh. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="instance">The instance to save into the cache.</param> /// <param name="loadContext"></param> public void Save <T>(T instance, LoadContext loadContext) where T : new() { if (instance == null) { throw new ArgumentNullException("instance"); } if (loadContext == null) { throw new ArgumentNullException("loadContext"); } var cacheEntry = Get <T>(loadContext, null, null, false); if (!cacheEntry.SerializeDataToCache(instance, DateTime.Now, null, true)) { throw new InvalidOperationException("Instance could not be serialized. Ensure that its DataLoader implements IDataLoader and the SerializeOptimizedData method properly serializes the data."); } else { cacheEntry.UpdateValue(instance, loadContext); } }
protected override object DeserializeCore(LoadContext identifier, XElement xml, Type objectType, Stream stream) { //<photosets cancreate="1"> // <photoset id="5" primary="2483" secret="abcdef" // server="8" photos="4" farm="1"> // <title>Test</title> // <description>foo</description> // </photoset> // <photoset id="4" primary="1234" secret="832659" // server="3" photos="12" farm="1"> // <title>My Set</title> // <description>bar</description> // </photoset> //</photosets> PhotosetListVm vm = new PhotosetListVm(identifier.Identity); vm.Photosets = new System.Collections.ObjectModel.ObservableCollection<PhotosetVm>(); foreach (var ps in xml.Elements("photoset")) { bool success; string id = TryGetValue(ps, "id", "", out success); PhotosetVm psvm = new PhotosetVm(id); psvm.Title = TryGetValue(ps, "title", null, out success); psvm.Description = TryGetValue(ps, "description", null, out success); psvm.PrimaryPhotoId = TryGetValue(ps, "primary", null, out success); vm.Photosets.Add(psvm); } return vm; }
/// <summary> /// Load an item. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="loadContext">The LoadContext for this item.</param> /// <param name="completed">An action to fire when the operation has successfully completed.</param> /// <param name="error">An action to fire if there is an error in the processing of the operation.</param> /// <returns>The instance of the item to use/databind to. As the loads complete, the properties of this instance will be updated.</returns> public T Load <T>(LoadContext loadContext, Action <T> completed, Action <Exception> error) where T : new() { var cacheItem = Get <T>(loadContext, completed, error, true); return((T)cacheItem.GetValue(false)); }
/// <summary> /// Load an item. /// </summary> /// <typeparam name="T">The type of the item to load.</typeparam> /// <param name="loadContext">The load context that describes this item's load.</param> /// <returns></returns> public T Load <T>(LoadContext loadContext) where T : new() { return(Load <T>(loadContext, null, null)); }
/// <summary> /// Non-generic version of load. /// </summary> public object Load(Type objectType, LoadContext loadContext) { return(Load(objectType, (object)loadContext)); }
public override LoadRequest GetLoadRequest(LoadContext context, Type objectType) { if (string.IsNullOrEmpty(Token)) { return null; } return new LocalCredentialsLoadRequest(context, Token); }
/// <summary> /// Create a WebLoadRequest /// </summary> /// <param name="loadContext"></param> /// <param name="uri">The URI to request</param> /// <param name="method">The method to request - GET or POST</param> /// <param name="data">The data for a POST request</param> public WebLoadRequest(LoadContext loadContext, Uri uri, string method, string data) : this(loadContext, uri) { Method = method; Data = data; }
/// <summary> /// Create a WebLoadRequest /// </summary> /// <param name="loadContext"></param> /// <param name="uri"></param> public WebLoadRequest(LoadContext loadContext, Uri uri) : base(loadContext) { Uri = uri; Method = "GET"; }
public LocalCredentialsLoadRequest(LoadContext context, string token) : base(context) { _token = token; }
internal static string BuildUniqueName(Type objectType, LoadContext context) { return(string.Format("{0}_{1}", objectType.Name, context.UniqueKey)); }
/// <summary> /// protected ctor. /// </summary> /// <param name="loadContext"></param> protected LoadRequest(LoadContext loadContext) { this.LoadContext = loadContext; }
/// <summary> /// Get the Entry for a given type/id pair and set it up if necessary. /// </summary> private CacheEntry Get <T>(object identity, Action <T> completed, Action <Exception> error, bool resetCallbacks) where T : new() { LoadContext loadContext = AutoCreateLoadContext <T>(identity); return(Get <T>(loadContext, completed, error, resetCallbacks)); }
protected abstract object DeserializeCore(LoadContext context, XElement xml, Type objectType, Stream stream);
protected WebLoadRequest BuildRequest(LoadContext context, string api, params FlickrArgument[] args) { string uri = FlickrClient.Current.BuildApiCall(api, true, false, false, args); return new WebLoadRequest(context, new Uri(uri)); }
protected override object DeserializeCore(LoadContext context, XElement xml, Type objectType, Stream stream) { // <photo id="2733" secret="123456" server="12" // isfavorite="0" license="3" rotation="90" // originalsecret="1bc09ce34a" originalformat="png"> // <owner nsid="12037949754@N01" username="******" // realname="Cal Henderson" location="Bedford, UK" /> // <title>orford_castle_taster</title> // <description>hello!</description> // <visibility ispublic="1" isfriend="0" isfamily="0" /> // <dates posted="1100897479" taken="2004-11-19 12:51:19" // takengranularity="0" lastupdate="1093022469" /> // <permissions permcomment="3" permaddmeta="2" /> // <editability cancomment="1" canaddmeta="1" /> // <comments>1</comments> // <notes> // <note id="313" author="12037949754@N01" // authorname="Bees" x="10" y="10" // w="50" h="50">foo</note> // </notes> // <tags> // <tag id="1234" author="12037949754@N01" raw="woo yay">wooyay</tag> // <tag id="1235" author="12037949754@N01" raw="hoopla">hoopla</tag> // </tags> // <urls> // <url type="photopage">http://www.flickr.com/photos/bees/2733/</url> // </urls> //</photo> var vm = new PhotoVm(context.Identity); bool s; vm.Title = TryGetValue(xml, "title", null, out s); vm.Description = TryGetValue(xml, "description", null, out s); var owner = xml.Element("owner"); vm.OwnerId = TryGetValue(owner, "nsid", null, out s); var dates = xml.Element("dates"); vm.Posted = FromUnixTime(TryGetValue(dates, "posted", null, out s)); var taken = TryGetValue(dates, "taken", null, out s); if (taken != null) { vm.Taken = taken; } vm.Updated = FromUnixTime(TryGetValue(dates, "lastupdate", null, out s)); ObservableCollection<PhotoTag> tags = new ObservableCollection<PhotoTag>(); foreach (var tag in xml.Element("tags").Elements("tag")) { bool success; PhotoTag pt = new PhotoTag { Tag = TryGetValue(tag, "raw", "", out success), RawTag = tag.Value, ID = TryGetValue(tag, "id", null, out success) }; tags.Add(pt); } vm.Tags = tags; return vm; }
/// <summary> /// Synchronously load an item from the cache. /// </summary> /// <typeparam name="T">The type of item to load</typeparam> /// <param name="loadContext">The item's LoadContext.</param> /// <returns>The cached value, or a default instance if one is not available.</returns> public T LoadFromCache <T>(LoadContext loadContext) where T : new() { var cacheItem = GetFromCache <T>(loadContext); return((T)cacheItem.GetValue(true)); }
/// <summary> /// Refresh an item's value /// </summary> /// <typeparam name="T">The type of item to load</typeparam> /// <param name="loadContext">The loadContext that identifies the item.</param> /// <param name="completed">An action to fire when the operation has successfully completed.</param> /// <param name="error">An action to fire if there is an error in the processing of the operation.</param> /// <returns>The instance of the item to use/databind to. As the loads complete, the properties of this instance will be updated.</returns> public T Refresh <T>(LoadContext loadContext, Action <T> completed, Action <Exception> error) where T : new() { Invalidate <T>(loadContext); return(Load <T>(loadContext, completed, error)); }
public override object Deserialize(LoadContext context, Type objectType, Stream stream) { var sr = new StreamReader(stream); var lc = new LocalCredentials(); try { Token = sr.ReadLine(); lc.UserId = sr.ReadLine(); if (!string.IsNullOrEmpty(Token) && !string.IsNullOrEmpty(lc.UserId)) { return lc; } } catch { } throw new InvalidOperationException("There was a problem validating your credentials."); }
internal static string BuildUniqueName(Type objectType, LoadContext context) { return string.Format("{0}_{1}", objectType.Name, context.UniqueKey); }
private CacheEntry Get <T>(LoadContext loadContext, Action <T> completed, Action <Exception> error, bool resetCallbacks) where T : new() { if (loadContext == null) { throw new ArgumentNullException("LoadContext required."); } object identity = loadContext.UniqueKey; CacheEntry value; lock (_objectCache) { if (_objectCache.ContainsKey(typeof(T)) && _objectCache[typeof(T)].TryGetValue(identity, out value)) { value.LoadContext = loadContext; if (resetCallbacks) { SetupCompletedCallback <T>(completed, error, value); } return(value); } } Type objectType = typeof(T); Action <CacheEntry> proxyCallback = cacheEntry => { var v = (T)cacheEntry.ValueInternal; foreach (var proxy in GetProxies <T>(cacheEntry.LoadContext)) { // copy the values over // ReflectionSerializer.UpdateObject(v, proxy.ProxyReference.Target, true, null); // fire the update notification // if (proxy.UpdateAction != null) { proxy.UpdateAction(); } } }; // create a new one. // value = new CacheEntry(loadContext, objectType, proxyCallback); value.NextCompletedAction.UnhandledError = OnUnhandledError; object loader = GetDataLoader(value); // How to create a new value. It's just a new. // value.CreateDefaultAction = () => { // if there is a proxy already registered, use it as the key value. // var proxy = GetProxies <T>(loadContext).FirstOrDefault(); if (proxy != null && proxy.ProxyReference != null && proxy.ProxyReference.IsAlive) { return(proxy.ProxyReference.Target); } var item = new T(); if (item is ILoadContextItem) { ((ILoadContextItem)item).LoadContext = value.LoadContext; } return(item); }; SetupCompletedCallback <T>(completed, error, value); // How to load a new value. // value.LoadAction = (lvl) => { if (loader == null) { throw new InvalidOperationException("Could not find loader for type: " + typeof(T).Name); } // get a loader and ask for a load request. // Debug.Assert(loader != null, "Failed to get loader for " + typeof(T).Name); var request = DataLoaderProxy.GetLoadRequest(loader, value.LoadContext, typeof(T)); if (request == null) { Debug.WriteLine("{0}: Aborting load for {1}, ID={2}, because {3}.GetLoadRequest returned null.", DateTime.Now, typeof(T).Name, value.LoadContext.Identity, loader.GetType().Name); return(false); } // fire off the load. // IsLoading = true; request.Execute( (result) => { if (result == null) { throw new ArgumentNullException("result", "Execute must return a LoadRequestResult value."); } if (result.Error == null) { lvl.OnLoadSuccess(result.Stream); } else { lvl.OnLoadFail(new LoadRequestFailedException(lvl.CacheEntry.ObjectType, value.LoadContext, result.Error)); } IsLoading = false; } ); return(true); }; // how to deserialize. value.DeserializeAction = (id, data, isOptimized) => { if (loader == null) { throw new InvalidOperationException("Could not find loader for type: " + typeof(T).Name); } // get the loader and ask for deserialization // object deserializedObject = null; if (isOptimized) { var idl = (IDataOptimizer)loader; if (idl == null) { throw new InvalidOperationException("Data is optimized but object does not implmenent IDataOptimizer"); } deserializedObject = idl.DeserializeOptimizedData(value.LoadContext, objectType, data); } else { deserializedObject = DataLoaderProxy.Deserialize(loader, value.LoadContext, objectType, data); } if (deserializedObject == null) { throw new InvalidOperationException(String.Format("Deserialize returned null for {0}, id='{1}'", objectType.Name, id)); } if (!objectType.IsInstanceOfType(deserializedObject)) { throw new InvalidOperationException(String.Format("Returned object is {0} when {1} was expected", deserializedObject.GetType().Name, objectType.Name)); } return(deserializedObject); }; // if this thing knows how to optimize, hook that up. // if (loader is IDataOptimizer) { value.SerializeOptimizedDataAction = (obj, stream) => { var idl = (IDataOptimizer)loader; return(idl.SerializeOptimizedData(obj, stream)); }; } // finally push the value into the cache. lock (_objectCache) { if (!_objectCache.ContainsKey(objectType)) { Dictionary <object, CacheEntry> typeDictionary = new Dictionary <object, CacheEntry>(); _objectCache[typeof(T)] = typeDictionary; } _objectCache[typeof(T)][identity] = value; } return(value); }
public object DeserializeOptimizedData(LoadContext context, Type objectType, System.IO.Stream stream) { StreamReader sr = new StreamReader(stream); string id = sr.ReadLine(); UserVm vm = new UserVm(id); vm.FullName = sr.ReadLine(); vm.UserName = sr.ReadLine(); vm.ProfileIconUrl = new Uri(sr.ReadLine()); return vm; }
protected override object DeserializeCore(LoadContext context, System.Xml.Linq.XElement xml, Type objectType, System.IO.Stream stream) { //<person nsid="12037949754@N01" ispro="0" iconserver="122" iconfarm="1"> // <username>bees</username> // <realname>Cal Henderson</realname> // <mbox_sha1sum>eea6cd28e3d0003ab51b0058a684d94980b727ac</mbox_sha1sum> // <location>Vancouver, Canada</location> // <photosurl>http://www.flickr.com/photos/bees/</photosurl> // <profileurl>http://www.flickr.com/people/bees/</profileurl> // <photos> // <firstdate>1071510391</firstdate> // <firstdatetaken>1900-09-02 09:11:24</firstdatetaken> // <count>449</count> // </photos> //</person> XElement personElement = xml; var user = new UserVm(personElement.Attribute("nsid").Value); user.ProfileIconUrl = UserVm.MakeIconUri(user.UserId, personElement.Attribute("iconfarm").Value, personElement.Attribute("iconserver").Value); bool success; user.UserName = personElement.Element("username").Value; user.FullName = TryGetValue(personElement, "realname", "", out success); return user; }