Moving to Github
So for the past couple of months I haven't been updating the source code here. Mainly because of time out issues with the repo. Not sure what is going on but it has pretty much convinced me to move to Github as my main repo. If I can ever get the repo to
work here, I'll update it but for now consider it pretty much static where it is.
The Github project also has all of the 4.0 version goodness in there. So if you want to contribute, go over there.
List of Features
Craig's Utility Library (or CUL, as in cull because I'm not that creative), was initially designed through a number of projects that I've worked on. Over time I assembled a number of classes to handle various tasks and continue to add a number of
items in my spare time. The library is written in C# and uses .Net 4.0 but many of the classes are usable in lower versions. More code can be found on my website:
Follow progress of the Next Version
For the next version of CUL, I want you to be able to see what I'm working on and be able to give feedback. In order to help with this, I've set up a board on Trello that will allow you to see the items that I'm currently working on, what's
done, and what is still in the planning stages. It should be public and you should have the ability to comment on every card and vote for items (more popular an item is, the more likely I am to push it forward faster). The board itself can be found here:
The easiest way to get CUL is to simply use NuGet:
There are also individual DLLs for each namespace available through NuGet. Whenever a new update is added to the library, a nightly build uploads a new version to NuGet. As such you're getting the latest version as soon as possible (or just download version
3.3.0002 [issue with auto numbering adds the 0002 even though it's actually straight 3.3]). Or if you can't use NuGet or simply aren't a fan, you can still download it here.
Source Code Repository
The repository here is Mercurial. Also note that there are repository mirrors available on Bitbucket and Github:
repositories. I'll be updating all three with changes as I make them.
Version 3.3 contains a number of changes. In fact if you pull it into an existing project, you may be wondering where everything went. For instance:
- The Exchange code has been removed (If you're using the Appointment class, you should use the new AppointmentSender in the Web.Email.SMTP namespace or VCalendar class in the FileFormats namespace).
- The Bing, Craigslist, Ebay, Hulu, Netflix, OAuth, OpenID, OpenSearch, and Twitter classes have been removed for different reasons (Mostly because I haven't used them in over a year, they weren't as great as some of the other libraries out there,
and some of the formats have changed
OAuth and I haven't kept up with it).
- Events namespace has been removed and merged into DataTypes (Utilities.DataTypes.EventArgs and Utilities.DataTypes.ExtensionMethods). The Raise functions should now be easier to call as they are simply extension methods now.
- Error namespace has been removed. Items from this namespace were moved to other locations (Web received anything based on HttpContext, Request, etc. Reflection received anything based on Assemblies. Environment received anything based on Processes.)
- CodeGen namespace has been removed. Items from this namespace have been made more generic and added to the DataTypes namespace in various forms (StringTemplate and FormatString extensions).
On top of that many extension methods and classes have been modified or combined in some way. The big items are Validation, Serialization, and SQLHelper. That said, there are a number of other changes:
- Switched ThrowIfTrue and ThrowIfFalse to ThrowIf and ThrowIfNot to be in line, from a naming standpoint, with the other extension methods. (Utilities.DataTypes.ExtensionMethods)
- Improved VCalendar code to hold more info.
- Switched ORM's Setup function to actually save the generated classes from the AOP (will change the code a bit more so this can be saved as a DLL).
- Made AOPManager get rid of its handle on the assembly builder once it's saved (to allow the data to be garbage collected)
- Made EmailSender IDisposable so that the attachments and embedded resources can be disposed of properly.
- Realized that the profiler is a bit too slow at present and working towards speeding it up.
- Trying to speed up SQLHelper a bit more (now faster than BLToolkit, slower than PetaPoco though...)
- Fixed IO extensions that took ~ to identify the app's location.
- Finished updates to SQLHelper such that batching and MicroORM items are now a part of it.
- Changed DbCommand's BeginTransaction to actually store the transaction in the command...
- Added ParameterBase class
- Created StringParameter and Parameter classes.
- Switched DbDataReader extensions to IDataReader.
- Modified Database code. It now holds a bit more info and can pull connection string info from the config file.
- Updated Database class to hold more information (DbType and Profile) and changed it to be a bit more thread safe (mappings has been changed to ConcurrentDictionary).
- Updated SQLHelper a bit more. It now stores database information so connection strings only need to be entered once, Profile info has been moved to the Database object, moved the database type info to the Database object, etc.
- Modified AddParameter extension method for DbCommand so that it no longer requires a length (it now uses the length of the value passed in for input parameters and nvarchar(max) for output parameters).
- Made DbCommandExtensions a bit more fluent in nature.
- Added a check to DirectoryInfo.SetAttributes for a null directory.
- Save extension method now takes a FileMode enum to specify how to handle creating/opening the file. (Utilities.IO.ExtensionMethods)
- All serialization functions have been condensed down to 4 functions (Serialize,Deserialize,SerializeBinary,DeserializeBinary). These functions now allow you to specify the serializer to use on the fly (so if you want to user JSON.Net, etc., you just need
to create the serializer object and feed it into the function). I'm not 100% happy with this and may change in the future. (Utilities.IO.ExtensionMethods)
- To go with this, serializers were created for binary, JSON, SOAP, and XML (more will be created as I go along and I plan to create a library to add external DLLs/libraries also).
- Fixed Median extension in Utilities.Math.ExtensionMethods
- Modified IObject in the ORM so that it started using new validation namespace.
- Modified ObjectBaseClass in the ORM so that it uses the new validation extension methods.
- Started updating validation section to use DataAnnotations.
- Moved a couple extension methods (Clamp, Min, and Max) from Math to DataTypes. (Utilities.DataTypes.ExtensionMethods)
- Switched Median to IEnumerable from List (Utilities.Math.ExtensionMethods)
- Moved ASCIIArt, BumpMap, MotionDetection, NormalMap, and OilPainting to extension methods. (Utilities.Media.Image.ExtensionMethods)
- Modified cache to use ConcurrentDictionary (should be faster).
- Modified Profiler class a bit so that it can track where the item was called from (Class/Method)
- Added a profiling option to MicroORM and SQLHelper (off by default)
- Simplified profiler a bit. It no longer uses ProfilerManager and is instead all in Profiler class.
- Profiler now allows sub items for timing purposes.
- Due to people actually asking to help or make changes, I've switched to xUnit.Net for unit testing to make things easier (still getting odd file issues at the moment) and I've switched to using Mighty Moose/AutoTest.Net to help speed up the testing
(usually takes 3 minutes each time I run all the tests).
- Modified Array extension Combine to allow multiple arrays to specified.
- Chain, Do, and Return were all very similar. As such they were combined. Chain is temporarily the function name. It now has a default return value (which is returned if the object or the function are null or the returned value from the function is null)
and default object value (which replaces the object prior to running the function if the object is null).
- If and NotIf extension was incorrectly returning the default value if the object was null. It now automatically returns null if the predicate is null.
- AddRange has been renamed Add and an Extension for Add that takes any number of items as params was added (parameters were reordered for this purpose).
- AddIf and AddIfUnique was modified to take any number of items as params (parameters were reordered for this purpose).
- RemoveRange was renamed to Remove.
- IDictionary's Sort extension has been added that now has the ability to specify how to sort (the default Sort is still available).
- A number of IEnumerable extensions were simplified.
- Modified FormatString extension. You can now specify a string formatter to be used.
- IsNullOrDBNull has been merged into IsNull (IsNull now checks for DBNull).
- NullCheck now uses IsNull (and thus will check for null or DBNull).
- ThrowIfNullOrDBNull has been removed (use ThrowIfNull instead).
- Fixed issue with ManyToOne mappings in the ORM if they are of the same type. Before it was saving to the join table multiple entries for each item without having a decisive parent/child relationship.
So if you're upgrading a project, it may take some time. However if you are starting a new project, the changes should make things a lot easier going forward. There have also been a large number of additions:
- Added IsAnagram extension method. (Utilities.DataTypes.ExtensionMethods)
- Added Exp, Log, and Log10 extension methods. (Utilities.Math.ExtensionMethods)
- Added a number of predicate extension methods that treat them as sets (AddToSet, CartesianProduct, Difference, Intersect, RelativeComplement, RemoveFromSet, and Union). (Utilities.Math.ExtensionMethods)
- Added a couple geometry classes (Circle, Rectangle, and Point).
- Added version of NullCheck that takes a Func instead of the object (for instances where it may take a while to create the object and/or it may be less likely that the object is null). (Utilities.DataTypes.ExtensionMethods)
- Added some ThrowIfNot* type extension methods. (Utilities.DataTypes.ExtensionMethods)
- Created a basic SQLCommand class for building SQL commands on the fly (will expand on this in the future).
- Added AppointmentSender class to Utilities.Web.SMTP that contains a VCalendar object and can send it using SMTP appropriately.
- Added per query caching to SQLHelper
- Added PositionOf extension for IEnumerable (Utilities.DataTypes.ExtensionMethods)
- Added Enums to ToDbType extension (Utilities.DataTypes.ExtensionMethods)
- Added GetOrCreateParameter to DbCommand (Utilities.SQL.ExtensionMethods)
- Added SetValue to IDictionary extensions.
- Added extension methods that will take a string as the file location and will save/read the corresponding file (instead of using FileInfo). This function also takes into account '~' and maps that to the path for the application/website. So you can
do "~/Data/File.txt".Save("Content"); now. (Utilities.IO.ExtensionMethods)
- Added GetValue function for IDictionary types. (Utilities.DataTypes.ExtensionMethods)
- Added the ability to recursively find all group members in LDAP code and added FindGroup code (based off of cn field).
- Finished adding profiling to ORM and simplified creation a bit (will be going further with this to make things as simple as possible).
- Finished IsCreditCard extension method for strings (Utilities.DataTypes.ExtensionMethods)
- Modified/Added new validation attributes: Cascade, Contains, DoesNotContain, Empty, MaxLength, MinLength, NotEmpty, NotInRange, Compare (which takes the place of Equal, GreaterThan, etc), CompareTo, Is (which is similar to DataType, but can check for valid
decimals, integers, credit cards, and domains), and Between.
- Finished adding comments to code.
- Added ToExpando (converts an object to an ExpandoObject) and version of TryTo that works with ExpandoObjects. (Utilities.DataTypes.ExtensionMethods)
- Added extension methods for caching data (allows for caching to multiple ASP.Net locations as well as the cache internal to CUL. Useful if your code may be run from a web app or windows app.) (Utilities.Caching.ExtensionMethods)
- Added methods for StackTrace and StackFrame for getting method information a bit easier. (Utilities.Environment.ExtensionMethods)
- Added Fraction class to Utilities.Math namespace.
- Added Salt extension that can be used to salt a string/byte array. (Utilities.Encryption.ExtensionMethods)
- Added Timing related extensions (allows easy timing of Funcs/Actions) (Utilities.Profiler.ExtensionMethods)
- Added AppendLineFormat extension for StringBuilder (Utilities.DataTypes.ExtensionMethods)
- Added 2 FormatString extensions that can be used to treat a string as a template (one uses an object and replaces the name of the property in the string with the value of the property. The other takes a series of key/value pairs and replaces the values
in the string accordingly) (Utilities.DataTypes.ExtensionMethods)
- Added IsNotNullOrEmpty extension. (Utilities.DataTypes.ExtensionMethods)
- Added various static char predicates, such as IsWhiteSpace (char.IsWhiteSpace) (Utilities.DataTypes.ExtensionMethods)
- Added ToString extension for Exceptions. It exports exception text, type, data, stack trace, source, target site, and any/all inner exceptions. (Utilities.DataTypes.ExtensionMethods)
- Added StringTemplate class that treats a string as a template (think mail merges, etc) and allows the addition/removal/changing of data between uses. (Utilities.DataTypes)
- Added TagDictionary class. This class acts as a dictionary but associates multiple keys with a single object (Think blog post as the object and cloud tags as the key) (Utilities.DataTypes)
- Added TaskQueue class. This class is designed to help in producer/consumer situations where actions need to be done in parallel but will arrive in sporadic intervals. (Utilities.DataTypes.Threading)
That concludes the changes in this release. Going forward I will be looking towards MVC specific code, speed increases to existing code, etc.