These forums have been archived and are now read-only.

The new forums are live and can be found at https://forums.eveonline.com/

EVE Technology Lab

 
  • Topic is locked indefinitely.
 

[EveLib] A .NET library for EveXML, CREST, EveCentral, and more

First post
Author
Icahmura Hasaki
Perkone
Caldari State
#41 - 2014-05-08 15:15:17 UTC
Ok, so I have changed structure of the AssetList class slightly. I won't normally make changes to the public API, but I don't think many are using it yet and the change does make quite a few things a lot easier.

response.Result.Assets is now response.Result.Items, and everything is Item objects now, with a LocationId of 0 unless it's a top level object. Also all contained items are in a list called Items.

I've also made a few other updates and fixes that doesn't change the public API, so if you want to download the newest version you should, before implementing too much using the old asset structure.

I can write you a way to flatten the assets as well if you want ?

Developer of EveLib and EveAuthUtility

Cryten Jones
Advantage Inc
#42 - 2014-05-08 15:16:00 UTC
All I did was to read the API return into an IXMLDom and then just ask for each [row] element disregarding the [rowset] so getting a flat list

Icahmura Hasaki
Perkone
Caldari State
#43 - 2014-05-08 15:20:52 UTC
I see, that is indeed much simpler. Anyways, I'll implement a flatten function as I imagine that could be useful for others as well. The previous change to the structure is on git, and I'll have the flatten function ready in a bit.

Developer of EveLib and EveAuthUtility

Icahmura Hasaki
Perkone
Caldari State
#44 - 2014-05-08 15:59:38 UTC
Added a function Flatten() to AssetList that returns a flat list with all the assets. Let me know if there are any issues :)

Developer of EveLib and EveAuthUtility

Cryten Jones
Advantage Inc
#45 - 2014-05-08 17:46:21 UTC
Cool, will have a play!

Do I just download the 1.2 zip file again? never understood git :-)

Cryten Jones
Advantage Inc
#46 - 2014-05-08 17:50:04 UTC
Also, on a totally new topic...

I want to have reasonably up to date prices in my app, and am planning a scheduled pull for what is effectively everything. This is because I then use this to generate a regular build price calculation for everything.

I have created an eve central class of my own that build multi item url's so that I am doing 10 * 90 item calls rather than 900 single item calls..

How what I don't know is:-

a: have a wasted my time again and you already do this
b: am I going to get the ban hammer :-)

I do make sure that I only check for items that exist & have a market group & are published so I think I follow the rules but I would love to know your view!



Icahmura Hasaki
Perkone
Caldari State
#47 - 2014-05-08 18:32:51 UTC  |  Edited by: Icahmura Hasaki
Don't use the zip under releases, they are very old. If you go to the main page of the repo, you can click Download ZIP on the right side, that will give you the newest version. It would make it a lot simpler if you used a git client though, as you could automatically get the newest versions and such. But that's up to you.

The library does not automatically segment requests. For evecentral requests you pass in an EveCentralOptions object, which has a List of itemIDs. If you want to segment, you add x amount of IDs to the lis and make a request. Clear the list and add the next X ids, repeat.

edt:
I added a new release zip that you can use too.

Developer of EveLib and EveAuthUtility

Cryten Jones
Advantage Inc
#48 - 2014-05-08 21:28:48 UTC
Thanks for all the help, I'll leave you in peace for now :-)
Icahmura Hasaki
Perkone
Caldari State
#49 - 2014-05-10 16:00:46 UTC
Another few updates. I've cleaned up the separation between http requests, deserialization and caching. It should be very easy to add your own cache implementation if you want to cache using eg. a database.

I'm also currently working on providing a range of methods for retrieving some basic of the data from the static database export. This is also done through http requests though, and is not meant for heavy usage. If you need to perform complex or many queries you should use a local database.

This is however a very lightweight alternative if you only need to request some basic data every now and again. I only just implemented GetInvTypes and GetInvType as a test, more should be coming shortly.

Developer of EveLib and EveAuthUtility

Icahmura Hasaki
Perkone
Caldari State
#50 - 2014-05-31 13:10:21 UTC
I am currently working on version 2 of the library. This version will be fully async, conforming to the Task-Based Asynchronous Pattern (TAP). I'm not sure whether to leave the sync methods in or not, as there is really no reason not to use the async versions. It will also include much improved tracing and debugging functionality, using System.Diagnostics. I will also use the major version update as an opportunity to make a few minor changes to the public API, as I don't want to change the api of the version 1.

Version 1.x has a new branch called "v1", so feel free up do with that as you please. Currently, EveMarketData has been implemented as async on master, and the others will follow soon.

I would also like to say that I appreciate any thanks, input, or other comments. It would be great to get an idea of who and how many are actually using this, to keep me motivated for further development :)

Developer of EveLib and EveAuthUtility

CCP FoxFour
C C P
C C P Alliance
#51 - 2014-05-31 13:40:11 UTC
Hey man,

Awesome to see all the work you have been doing on this library. I have added it to the Wiki list of EVE API libraries here: https://wiki.eveonline.com/en/wiki/EVE_API_Libraries

You probably wont want to do it until you are done your v2 of the library but consider also adding a basic example of it's usage here: https://wiki.eveonline.com/en/wiki/EVE_API_Getting_Started

Since you are also about the only one doing .NET stuff it would be great to see a raw .NET example there as well. :D

@CCP_FoxFour // Technical Designer // Team Tech Co

Third-party developer? Check out the official developers site for dev blogs, resources, and more.

Lien Rollard
Imperial Academy
Amarr Empire
#52 - 2014-05-31 14:49:42 UTC
Very nice work. I have a few question.

1) Do you expect alot of changes to the method names or the global structure of the library with the Async changes? (I suspect not but I'd rather ask)


2) Do you have a specific reason as to why you're not throwing Exceptions on the Contracts?

Quote:
Example:
- Contract.Requires(options.Stations != null);

Why not (general exception, could be more specific):
Contract.Requires < EveLibException > (options.Stations != null);


I'm asking this because the current way doesn't allow for easy feedback when something goes wrong.
I've been thinking of implementing these exceptions on the version I'm using. I'll probably fork / pull request


Keep up the good work anyway. You're encouraging me to actually begin coding on a market/corp application.
Icahmura Hasaki
Perkone
Caldari State
#53 - 2014-05-31 15:19:46 UTC
Funny you'd ask about the library changes, I've been contemplating this exact issue for the past few hours. By convention the new methods have to be named using an "Async" postfix. So the question is whether I should remove the old synchronous methods or not. And if I keep them, do I just wrap the async methods and block, or do I keep a separate fully sync implementation.

From a maintenance and clarity perspective, removing the synchronous methods would be much easier. If someone really wants to avoid using async, they can still use SomeMethodAsync().Result with the implications that causes.

I really can't seem to decide how to do it. If anyone has any input, that would be greatly appreciated.

About the code contracts, MS recommends using the non-generic version of Requires unless backward compatibility with old DataContracts versions force you use the generic one. I have to admit I haven't used CodeContracts much, and I've been considering removing it all together but haven't had the time to look into it further. The non-generic one does however also throw an Exception if the contract is violated, just not a user specified one.

Developer of EveLib and EveAuthUtility

Icahmura Hasaki
Perkone
Caldari State
#54 - 2014-05-31 15:30:05 UTC
CCP FoxFour wrote:
Hey man,

Awesome to see all the work you have been doing on this library. I have added it to the Wiki list of EVE API libraries here: https://wiki.eveonline.com/en/wiki/EVE_API_Libraries

You probably wont want to do it until you are done your v2 of the library but consider also adding a basic example of it's usage here: https://wiki.eveonline.com/en/wiki/EVE_API_Getting_Started

Since you are also about the only one doing .NET stuff it would be great to see a raw .NET example there as well. :D


Hey, that's greatly appreciated!

I will make sure to add some examples there, once I get the public API for 2.0 finalized. I should also add that there is a pretty comprehensive readme on github, with details and code examples.

And I'll have a look at the raw example, but C# can be quite verbose at times, compared to the neater php and python examples. I could add something simple for querying an endpoint, any sensible XML parsing might take too much space though.

Developer of EveLib and EveAuthUtility

Lien Rollard
Imperial Academy
Amarr Empire
#55 - 2014-05-31 15:31:52 UTC  |  Edited by: Lien Rollard
To be honest, multithreading is the way most applications run these days.
Due to the Await-Async implementation it has made the usage of multithreading alot easier. I hardly use non-async methods these days.

However I understand some people refraining from the multithreading. Personally I would go with the "Async" postfix with the non-async methods being blocked versions of the async ones. It allows for easier debugging & testing since you're basically testing the same in 2 seperate "methods".

I feel a user of a library is still responsable for how he/she handles the return of the methods exposed inside it. If the user feels like using the non-Async methods, the user should know the implications. Same for the async methods.

About the Code Contracts, thanks for the information. I never used Contracts before mostly due to never hearing about it till now. If you go about removing it, would you go back to the normal if-else clauses or search for different solution?
Icahmura Hasaki
Perkone
Caldari State
#56 - 2014-05-31 15:43:25 UTC
Yes, I will probably keep the old methods, and just add Async versions of them.

About the contracts, I'm not entirely sure the library needs it. The parameters aren't very complex, and are well documented by both the relevant API documentation (eve central, eve marketdata and so on) and in the comments for each method.

If you want to use code contracts however, you should probably download http://visualstudiogallery.msdn.microsoft.com/1ec7db13-3363-46c9-851f-1ce455f66970 if you're using visual studio.

I'll probably keep them around for version 2 at least, but as always feedback is welcome.

Developer of EveLib and EveAuthUtility

Icahmura Hasaki
Perkone
Caldari State
#57 - 2014-05-31 17:23:16 UTC
I've updated all modules, except EveOnline.Image, to include Async versions of all methods. What is available on the master now will be the final API for version 2.0, bar minor bugs that might have passed the unit tests.

I might add support for progress reporting and task cancellation, but in a way that doesn't affect the current api.

I would greatly appreciate any feedback or help with debugging the async methods, as well as the regular ones.

Also, keep in mind that async does not mean that the library is automagically multithreaded. Some methods may still be CPU bound during deserialization. However, the library shouldn't block on any IO operations (disk access, web requests) if you use the async api.

Developer of EveLib and EveAuthUtility

Lien Rollard
Imperial Academy
Amarr Empire
#58 - 2014-05-31 17:56:45 UTC
I have forked your Library and am adding a small module for EMDR (for those who want to have the data directly instead of via Eve-Central/Market/Etc)

Very nice work on the v2.0 api. That was quick!
Icahmura Hasaki
Perkone
Caldari State
#59 - 2014-05-31 22:34:45 UTC  |  Edited by: Icahmura Hasaki
It seems I was a bit too quick on the trigger regarding the final API. I need to figure out how to deal with the lazy loading of properties in CharacterKey and CorporationKey.

My current options are:
1. Provide a separate method, InitAsync(), which loads all properties in async fashion. Accessing any properties for the first time without first calling InitAsync(), will load the properties synchronously.

2. Provide properties which lazy loads synchronously (as it is currently), and a separate method named GetSomePropertyAsync(), which provides the async behaviour. I don't like the fact that I'll have to mix properties and methods for accessing the same fields though.

3. Provide properties named SomePropertyAsync, which lazy loads asynchronously. This might be the most elegant solution, but it also seems to go against many conventions for properties, and isn't directly supported so I'd have to use some dirty code.

4. Remove all properties, and only provide methods, like GetSomeProperty() and GetSomePropertyAsync(). This will make the API more consistent than mixing properties for sync and methods for async operations, but will break backwards compatibility for this part of the api.

Any input would be welcome Ugh

Developer of EveLib and EveAuthUtility

Icahmura Hasaki
Perkone
Caldari State
#60 - 2014-06-01 11:46:24 UTC
So I've narrowed it down to option 1 or 4, unless someone has any other ideas.

Option 1 would preserve current functionality, but with an added InitAsync() method. So if you want to use it synchronously it would be used as it is now, and if you want async, you would need to call this explicitly before accessing any properties.
So following InitAsync, all access to properties will be instant without the need for any async methodology. And obviously you don't have to call InitAsync on object creation, you can defer it to a point where you are certain you will have to load the data.
Quote:
CharacterKey key = await new CharacterKey(keyId, vCode).InitAsync();
string accessMask = key.AccessMask;
Character c = key.Characters.First();



Or the other option, which avoids the explicit initiation and allows lazy loading of the data on demand, but also requires async methodology for access to each property on the key.
Quote:
CharacterKey key = new CharacterKey(keyId, vCode);
string accessMask = await key.GetAccessMaskAsync();
Character c = (await key.GetCharactersAsync()).First();


I've currently implemented both, but this makes the API unnecessarily complex, so I'll be removing one of them. I'm currently leaning towards using the first option, but I'm fairly new to TAP and .NET in general so any input would be welcome :)

Developer of EveLib and EveAuthUtility