-- begin VERSIONING --------------------------------------------------------------------------------------------------------------------- https://github.com/rmcrackan/Libation/releases v3.0.3 : Switch to SQLite. No longer relies on LocalDB, which must be installed separately v3.0.2 : Final using LocalDB v3.0.1 : Legacy inAudible wire-up code is still present but is commented out. All future check-ins are not guaranteed to have inAudible wire-up code v3.0 : This version is fully powered by the Audible API. Legacy scraping code is still present but is commented out. All future check-ins are not guaranteed to have any scraping code v2 : new library page scraping. still chrome cookies. all decryption is handled natively. no inAudible dependency v1 : old library ajax scraping. wish list scraping. chrome cookies. directly call local inAudible. .net framework -- end VERSIONING --------------------------------------------------------------------------------------------------------------------- -- begin HOW TO PUBLISH --------------------------------------------------------------------------------------------------------------------- OPTION 1: UI rt-clk project project > Publish... click Publish OPTION 2: cmd line change dir to folder containing project cd C:\[full...path]\Libation\LibationWinForm this will use the parameters specified in csproj dotnet publish -c Release OPTION 3: cmd line, custom open csproj remove: PublishTrimmed, PublishReadyToRun, PublishSingleFile, RuntimeIdentifier run customized publish. examples: publish all platforms dotnet publish -c Release publish win64 platform only dotnet publish -r win-x64 -c Release publish win64 platform, single-file dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true -- end HOW TO PUBLISH --------------------------------------------------------------------------------------------------------------------- -- begin AUDIBLE DETAILS --------------------------------------------------------------------------------------------------------------------- alternate book id (eg BK_RAND_006061) is called 'sku' , 'sku_lite' , 'prod_id' , 'product_id' in different parts of the site -- end AUDIBLE DETAILS --------------------------------------------------------------------------------------------------------------------- -- begin SOLUTION LAYOUT --------------------------------------------------------------------------------------------------------------------- core libraries extend Standard Libraries additional simple libraries for general purpose programming utils: domain ignorant domain: biz logic db ignorant db, domain objects domain internal utilities: domain aware. db ignorant domain utilities: domain aware. db aware incl non-db persistence. unless it needs to be tied into a db intercepter all user-provided data must be backed up to json application do NOT combine jsons for - audible-scraped persistence: library, book details - libation-generated persistence: FilePaths.json - user-defined persistence: BookTags.json -- end SOLUTION LAYOUT --------------------------------------------------------------------------------------------------------------------- -- begin EF CORE --------------------------------------------------------------------------------------------------------------------- transaction notes ----------------- // https://msdn.microsoft.com/en-us/data/dn456843.aspx // Rollback is called by transaction Dispose(). No need to call it explicitly using var dbContext = new LibationContext(); using var dbContextTransaction = dbContext.Database.BeginTransaction(); refreshAction(dbContext, productItems); dbContext.SaveChanges(); dbContextTransaction.Commit(); aggregate root is transactional boundary // //context.Database.CurrentTransaction //var dbTransaction = Microsoft.EntityFrameworkCore.Storage.DbContextTransactionExtensions.GetDbTransaction(context.Database.CurrentTransaction); // // test with and without : using TransactionScope scope = new TransactionScope(); //System.Transactions.Transaction.Current.TransactionCompleted += (sender, e) => { }; // also : https://docs.microsoft.com/en-us/dotnet/api/system.transactions.transaction.enlistvolatile pattern when using 1 db context per form public Ctor() { InitializeComponent(); // dispose context here only. DO NOT dispose in OnParentChanged(). parent form will call dispose after this one has been switched. // disposing context prematurely can result in: // The ObjectContext instance has been disposed and can no longer be used for operations that require a connection. this.Disposed += (_, __) => context?.Dispose(); } -- end EF CORE --------------------------------------------------------------------------------------------------------------------- -- begin ASYNC/AWAIT --------------------------------------------------------------------------------------------------------------------- Using Async and Await to update the UI Thread – Stephen Haunts { Coding in the Trenches } https://stephenhaunts.com/2014/10/14/using-async-and-await-to-update-the-ui-thread/ Using Async and Await to update the UI Thread Part 2 – Stephen Haunts { Coding in the Trenches } https://stephenhaunts.com/2014/10/16/using-async-and-await-to-update-the-ui-thread-part-2/ Simple Async Await Example for Asynchronous Programming – Stephen Haunts { Coding in the Trenches } https://stephenhaunts.com/2014/10/10/simple-async-await-example-for-asynchronous-programming/ Async and Await -- Stephen Cleary's famous intro https://blog.stephencleary.com/2012/02/async-and-await.html Async-Await - Best Practices in Asynchronous Programming -- Stephen Cleary https://msdn.microsoft.com/en-us/magazine/jj991977.aspx -- end ASYNC/AWAIT ---------------------------------------------------------------------------------------------------------------------