{"id":23201409,"url":"https://github.com/jlyonsmith/ncontrib","last_synced_at":"2025-04-05T09:27:12.477Z","repository":{"id":14358645,"uuid":"17068372","full_name":"jlyonsmith/ncontrib","owner":"jlyonsmith","description":"An attempt to extend the .NET framework with extension methods, helper classes, and new objects to allow developers to write less code, more readable code, and use well-tested encapsulations of common functionality. I want to write less code, declare fewer variables, and generally have a more fluid feel to the code. Workin' on that.","archived":false,"fork":false,"pushed_at":"2013-11-08T15:56:55.000Z","size":496,"stargazers_count":0,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-29T08:09:33.773Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"veracross/ncontrib","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jlyonsmith.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-02-21T20:15:32.000Z","updated_at":"2014-02-21T20:15:33.000Z","dependencies_parsed_at":null,"dependency_job_id":"fdbde794-b305-4257-abf3-fcad242480a5","html_url":"https://github.com/jlyonsmith/ncontrib","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jlyonsmith%2Fncontrib","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jlyonsmith%2Fncontrib/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jlyonsmith%2Fncontrib/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jlyonsmith%2Fncontrib/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jlyonsmith","download_url":"https://codeload.github.com/jlyonsmith/ncontrib/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247315266,"owners_count":20919015,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-18T15:15:02.538Z","updated_at":"2025-04-05T09:27:12.457Z","avatar_url":"https://github.com/jlyonsmith.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cstyle type=\"text/css\"\u003e\n    pre \u003e code {\n        display: block;\n        padding: .5em;\n        background-color: #eee;\n        border: solid 1px #bbb;\n    }\n\u003c/style\u003e\n\nNContrib\n========\n\nAn attempt to extend the .NET framework with extension methods, helper classes, and new objects\nto allow developers to write less code, more readable code, and use well-tested encapsulations of common functionality.\nI want to write less code, declare fewer variables, and generally have a more fluid feel to the code. Workin' on that.\n\nBackground\n----------\n\nNearly all functionality in NContrib was born out of my own personal need/desire whilst developing various applications,\nso you may find unexpected gaps in functionality. That's just because I haven't had the need yet. I have tried to anticipate\nsome obvious needs, but there's no use going off on a tangent coding without purpose. I like all the additions to be considered,\nnecessary, and adding value.\n\nStructure\n---------\n\nThe solution is broken up into several projects\n\n* NContrib - Targets .NET 3.5 and is the core projects\n* NContrib.Drawing - Targets .NET 3.5 and provides helpers and extensions related to System.Drawing functionality\n* NContrib.International - Targets .NET 3.5 and provides functionality for projects with multi-national reach\n* NContrib4 - Targets .NET 4 and contains code that can only run on .NET 4, such as dynamics\n\nAnd two projects for examples and unit testing\n\n* NContrib.Examples\n* NContrib.Tests\n\nFAQ\n---\n\n**Q. Why are you using Q\u0026R brace-styles?**\n\nBecause it is the right way of doing it ;) But in all seriousness, if it becomes a problem for would-be developers I'd be willing to use the .NET default\n\n**Q. Can you add some functionality for me?**\n\nThis is an open-source project so you could fork it and issue a pull request.\nBut I understand not being comfortable with adding code. If you would like something added, sure, ask and we'll talk.\n\nExamples\n--------\n\n(Documentation is far from complete)\n\n### String extensions\n\n**ContainsOnly**\n    \n    \"XL\".ContainsOnly('S', 'M', 'L', 'X')\n    =\u003e true\n\n**DigitAt**\n    \n    \"070-605 91 23\".DigitAt(1)\n    =\u003e 7\n\n**FromIndexOf**\n\n    \"S-21144\".FromIndexOf(\"-\")\n    =\u003e 21144\n\n**Join**\n    \n    new[] {\"Sweden\", \"Denmark\", \"Norway\",}.Join(\", \")\n    =\u003e Sweden, Denmark, Norway\n\n**Inject**\n\n    \"Hello, {Name}. Today is {Today:dd-MM-yyyy}\".Inject(new { Name = \"Mike\", Today = DateTime.Now })\n    =\u003e Hello, Mike. Today is 21-04-2011\n    \n**IsBlank**\n\n    \" \".IsBlank()\n    =\u003e true\n\n    ((string)null).IsBlank()\n    =\u003e true\n    \n    \" \".IsBlank()\n    =\u003e true\n\n**IsEmpty**\n    \n    \"\".IsEmpty()\n    =\u003e true\n    \n    \" \".IsEmpty()\n    =\u003e false\n\n**IsDigits**\n\n    \"12345\".IsDigits()\n    =\u003e true\n\n**IsLetters**\n    \n    \"asd\".IsLetters()\n    =\u003e true\n\n**IsLettersOrDigits**\n    \n    \"S99\".IsLettersOrDigits()\n    =\u003e true\n\n**IsNotBlank**\n    \n    \"hello\".IsNotBlank()\n    =\u003e true\n\n**IsNotEmpty**\n    \n    \"haj\".IsNotEmpty()\n    =\u003e true\n    \n**Left**\n\n    \"hello\".Left(2)\n    =\u003e he\n\n**Repeat**\n    \n    @\"/!\\\".Repeat(5)\n    =\u003e /!\\/!\\/!\\/!\\/!\\\n\n**Right**\n    \n    \"there\".Right(2)\n    =\u003e re\n\n**ToCamelCase**\n\n    \"transaction-id\".CamelCase()\n    =\u003e transactionId\n\n**ToPlural**\n\n    \"cat\".ToPlural()\n    =\u003e cats\n    \n    \"cat\".ToPlural(1)\n    =\u003e cat\n    \n    \"moose\".ToPlural()\n    =\u003e moose\n    \n    \"leaf\".ToPlural()\n    =\u003e leaves\n    \n**ToSingular**\n    \n    \"knives\".ToSinglar()\n    =\u003e knife\n    \n    \"mice\".ToSingular()\n    =\u003e mouse\n    \n**ToSnakeCase**\n    \n    \"transactionId\".SnakeCase()\n    =\u003e transaction_id\n\n**ToTitleCase**\n    \n    \"BANK OF AMERICA N.A.\".ToTitleCase()\n    =\u003e Bank of America N.A.\n    \n    \"JPMORGAN CHASE BANK USA\".ToTitleCase(new [] { \"JPMorgan\", \"USA\" })\n    =\u003e JPMorgan Chase Bank USA\n    \n    \"o'leary's pub\".ToTitleCase()\n    =\u003e O'Leary's Pub\n    \n**UntilIndexOf**\n    \n    \"Boston, MA\".UntilIndexOf(\",\")\n    =\u003e Boston\n\n**W**\n    \n    \"id first_name last_name\".W().Describe()\n    =\u003e [id, first_name, last_name]\n\n**Words**\n    \n    \"Öresundståg-mot-Kastrup-Köpenhamn-Helsingør-84\".Words().Describe()\n    =\u003e [Öresundståg, mot, Kastrup, Köpenhamn, Helsingør, 84]\n    \n    \n    \"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean lectus sem, facilisis convallis vestibulum vel, tincidunt nec dolor.\".Wrap(40)\n    =\u003e\n    Lorem ipsum dolor sit amet,\n    consectetur adipiscing elit. Aenean\n    lectus sem, facilisis convallis\n    vestibulum vel, tincidunt nec dolor.\n    \n    \"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean lectus sem, facilisis convallis vestibulum vel, tincidunt nec dolor.\".Wrap(40, TextWrapMethod.HardBreakAlways)\n    =\u003e\n    Lorem ipsum dolor sit amet, consectetur\n    adipiscing elit. Aenean lectus sem, faci\n    lisis convallis vestibulum vel, tincidun\n    t nec dolor.\n\n### DateTime Extensions\n\n**ToTimeZone**\n\n    var date = DateTime.UtcNow\n    =\u003e 2011-04-08 20:11:37\n    \n    date.ToTimeZone(\"Tokyo Standard Time\")\n    =\u003e 2011-04-09 05:11:37\n\n### Object extensions\n\n**CopyPropertiesFrom**\n    \n    var myPerson = new Person { FirstName = \"Reginald\", LastName = \"Bäckström\" }\n    myPerson.CopyPropertiesFrom(new { FirstName = \"Mike\", LastName = \"Jönsson\" })\n    =\u003e FirstName = \"Mike\", LastName = \"Jönsson\"\n\n**ConvertTo**\n    \n    \"123.45\".ConvertTo\u003cdecimal\u003e(CultureInfo.InvariantCulture)\n    =\u003e 123.45\n    \n    \"False\".ConvertTo\u003cbool\u003e()\n    =\u003e False\n    \n    \"StoredProcedure\".ConvertTo\u003cCommandType\u003e()\n    =\u003e CommandType.StoredProcedure\n\n**In**\n\n    4.In(1, 2, 3, 4, 5)\n    =\u003e true\n    \n    \"Dave\".In(\"Carter\", \"Dave\", \"Steffan\")\n    =\u003e true\n\n\n### Working with a data result\n\nWithout NContrib, this is how you might connect to a database, execute a procedure, and read its results into a dictionary\n\n    var currencies = new Dictionary\u003cstring, decimal\u003e();\n    \n    using (var cn = new SqlConnection(\"server=myserver;database=resources;uid=services;pwd=passw0rd;encrypt=yes\"))\n    using (var cmd = new SqlCommand(\"Get_Currency_Conversions\", cn)) {\n        cn.Open();\n        cmd.CommandType = CommandType.StoredProcedure;\n        cmd.Parameters.AddWithValue(\"currency\", \"EUR\");\n        cmd.Parameters.AddWithValue(\"amount\", 123.45m);\n        using (var dr = cmd.ExecuteReader()) {        \n            while (dr.Read()) {\n                currencies.Add(dr.GetString(dr.GetOrdinal(\"name\")),\n                                dr.GetDecimal(dr.GetOrdinal(\"rate\")));\n            }\n        }\n    }\n    \nUsing some helper objects and extension methods in NContrib, you can do the same thing like this:\n\n    var currencies = SqlUri.OpenConnection(\"mssqls://services:passw0rd@localhost/resources\")\n        .CreateCommand(\"Get_Currency_Conversions\", CommandType.StoredProcedure)\n        .AddParameters(new { Currency = \"EUR\", Amount = 123.45m })\n        .ExecuteReader()\n        .Transform(dr =\u003e new {\n            CurrencyCode = dr.GetValue\u003cstring\u003e(\"name\"),\n            Rate = dr.GetValue\u003cdecimal\u003e(\"rate\"),\n        })\n        .ToDictionary(x =\u003e x.CurrencyCode, x =\u003e x.Rate);\n\nBetter? Yes, we can do better.\n\nSince there's an extension method for executing a stored procedure and returning a dictionary, we could do this instead:\n\n    var currencies = SqlUri.OpenConnection(\"mssqls://services:passw0rd@localhost/resources\")\n        .CreateCommand(\"Get_Currency_Conversions\", CommandType.StoredProcedure)\n        .AddParameters(new { Currency = \"EUR\", Amount = 123.45m })\n        .ExecuteDictionary\u003cstring, decimal\u003e(\"name\", \"rate\");\n\n### MIME\n\n    MimeHelper.GetMimeFromFileName(\"data.docx\")\n    =\u003e application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\n    \n    MimeHelper.GetMimeFromBytes(@\"c:\\temp\\a-jpg-without-a-file-ext\");\n    =\u003e image/jpeg\n\n### Luhn checksum and generation\n    \n    Luhn.IsValid(\"354957031609855\")\n    =\u003e true\n    \n    Luhn.Generate(16, \"4581\")\n    =\u003e 4581555790158762\n\n### Range\n    \n    var r = new Range\u003cint\u003e(10, 20)\n    r.Includes(5)\n    =\u003e true\n    \n    r.Includes(20)\n    =\u003e true\n    \n    var r = new Range\u003cint\u003e(10, 20, minInclusive: true, maxInclusive: false)\n    r.Includes(10)\n    =\u003e true\n    \n    r.Includes(19)\n    =\u003e true\n    \n    r.Includes(20)\n    =\u003e false","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjlyonsmith%2Fncontrib","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjlyonsmith%2Fncontrib","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjlyonsmith%2Fncontrib/lists"}