builder.Services.AddCouchbase(options =>
{
options.ConnectionString = "couchbase://localhost";
options.UserName = "Administrator";
options.Password = "password";
});
// this adds auth to CMSprinkle
// if don't do this, it will be local only
// ExampleAuthClass enables anonymous public access, so don't use it as-is!
// builder.Services.AddTransient<ICMSprinkleAuth, ExampleAuthClass>();
// this adds CMSprinkle to your project
builder.Services.AddCMSprinkle(options =>
{
// changes URL for cmsprinkle pages
// if not specified, default is "cmsprinkle"
// then URLs would be /cmsprinkle/home, etc
options.RoutePrefix = "managecontent";
// what message you want to show up when the
// content hasn't been created yet
// there is a default message if you don't specify this
options.ContentNotFoundMessage = (contentKey) => $"ERROR: Can't find {contentKey}, did you add it yet?";
});
// this adds a Couchbase connection to CMSprinkle
builder.Services.AddCMSprinkleCouchbase("Example","_default","_default", createCollectionIfNecessary: true);
// or here's the SQLServer provider
// builder.Services.AddCMSprinkleSqlServer("Server=localhost;Database=Example;User Id=sa;Password=yourStrong(!)Password;TrustServerCertificate=True;", "SprinkleContent", "dbo", createTableIfNecessary: true);
Short version:
The 2024 C# Advent is now open for contributors to sign up! If you've participated before, I suggest you visit https://csadvent.christmas to claim your spot right away!
Long version:
The C# Advent is an annual event, showcasing content (blog posts, videos, articles, podcast episodes, whatever!) from C# developers and enthusiasts, every day, from December 1st to December 25th.
Each day will feature two pieces of content. Each piece of content links back to the main C# Advent site, like an old fashioned webring.
What do I have to do to participate?
Right now: just sign up. Go to https://csadvent.christmas, look for an open spot, and claim it. You'll receive an email with a special link. Click that link, fill out the form, and you're in! You do NOT need to tell me a title, topic, idea, or anything like that at this stage.
I'll also be adding you to an exclusive mailing list, with reminders, tips, and C# Advent news.
What do I do after I claim a spot?
Work on some content. It must be C# related and it must link back to https://csadvent.christmas, but otherwise, it can be whatever you'd like. Historically, it's mostly blog posts, but there's also been videos and podcast episodes. Any content that can be linked to is fine with me!
Do I give you the content to publish?
No! Publish it on your website, YouTube channel, podcast, whatever. That's the whole point: to help you get attention and noticed by the C# community.
When must I have it finished?
Technically, you don't need to have it done until the day that you claimed. I'd recommend that you get it done before then, because December is a busy holiday time for many of us. Just don't make it public until the day you signed up for.
What does "Advent" mean?
Advent is a season leading up to Christmas Day. Advent Calendars mark the days until Christmas. For children, the marking of each day might include a piece of candy or a small toy.
What are some good examples of C# Advent content?
ANY and ALL content that's related to C# is good in my book. The point is to promote the community, our love of C#, and to lift everyone up! However, if you're looking for some good examples, check out the C# Advent archives from 2023 (and earlier) Awards, to see what was popular.
But remember: you don't have to do anything flashy! If you care about C# and you've got something you want to share, I want you to claim a spot!
How long have you been doing this?
The first C# Advent calendar was in 2017.
You're out of open spots! I missed it!
Maybe not! December can be a hectic month, and sometimes people need to drop out. If you want to be on standby, fill out this form. Being on standby is one of the hardest jobs, since people may drop out with very little notice. But, if you are up to the task, I very much appreciate it, and I'm willing to accomodate or help you in any way I can.
Today, I’m presenting my C# Advent entry for December 25th, a project that emerged from the C# Advent series: CMSprinkle. (By the way, C# Advent merch is still on sale, but not for much longer).
What is CMSprinkle?
CMSprinkle is a micro content management system I developed specifically for the C# Advent website. Its creation was driven by the need for a straightforward and efficient way to manage small bits of content without the overhead of a full-blown CMS or even a headless CMS.
Features and Functionality
CMSprinkle is now available on NuGet and GitHub. It’s designed for ASP.NET Core web applications, particularly MVC projects. (It may also be adaptable to other ASP.NET Core projects, though this remains untested).
Here’s a quick walkthrough of setting up a new project with CMSprinkle:
-
Creating a New Project: Start with a new ASP.NET Core web application, targeting .NET 8. (Alternatively, you should be able to add CMSprinkle to any existing ASP.NET Core web project that you already have available).
-
Installing CMSprinkle: Add CMSprinkle from NuGet to your project. (
dotnet add package CMSprinkle
) -
Choosing a Data Provider: Select from available data providers like Couchbase (used by the C# Advent site) or SQL Server. The system is designed to be extensible, so feel free to contribute or request additional database support.
-
Setting Up: After adding CMSprinkle, you’ll configure it in the views and program files: set up a tag helpers, and add services in your startup.
Managing Content
CMSprinkle aims to reduce friction in adding a CMS to your site. You define content keys directly in tag helpers and configure options like custom error messages for unfound content.
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://learn.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
@* this is how you sprinkle managed content into your pages *@
@* make sure you add CMSPrinkle in _ViewImports.cshtml first *@
@* this will say "ERROR: Content Not Found (HelloWorld)" until you actually create the content.*@
<CMSprinkle contentKey="HelloWorld" />
</div>
The system also includes a management console for easy content addition and editing.
A Focus on Minimalism
The guiding principle of CM Sprinkle is minimalism. It’s ideal for existing ASP.NET Core websites that require very modest content management capabilities without the complexity of a full CMS. If you have specific features in mind that would make CMSprinkle more suitable for your project, feel free to submit an issue to the GitHub repository.
Video Introduction
You can watch a video introduction to CMSprinkle here, showing a demo in action:
Join the C# Advent Celebration
I invite you to dive into the rich collection of C# Advent entries for 2023. With 50 total entries on https://csadvent.christmas, there’s something for everyone.
I wish everyone a Merry Christmas and a Happy New Year! Thank you for participating in the C# Advent, and I hope to see you again next year.
Short version:
The 2023 C# Advent is now open for contributors to sign up! If you've participated before, I suggest you visit https://csadvent.christmas to claim your spot right away!
Long version:
The C# Advent is an annual event, showcasing content (blog posts, videos, articles, podcast episodes, whatever!) from C# developers and enthusiasts, every day, from December 1st to December 25th.
Each day will feature two pieces of content. Each piece of content links back to the main C# Advent site, like an old fashioned webring.
What do I have to do to participate?
Right now: just sign up. Go to https://csadvent.christmas, look for an open spot, and claim it. You'll receive an email with a special link. Click that link, fill out the form, and you're in! You do NOT need to tell me a title, topic, idea, or anything like that at this stage.
I'll also be adding you to an exclusive mailing list, with reminders, tips, and C# Advent news.
What do I do after I claim a spot?
Work on some content. It must be C# related and it must link back to https://csadvent.christmas, but otherwise, it can be whatever you'd like. Historically, it's mostly blog posts, but there's also been videos and podcast episodes. Any content that can be linked to is fine with me!
Do I give you the content to publish?
No! Publish it on your website, YouTube channel, podcast, whatever. That's the whole point: to help you get attention and noticed by the C# community.
When must I have it finished?
Technically, you don't need to have it done until the day that you claimed. I'd recommend that you get it done before then, because December is a busy holiday time for many of us. Just don't make it public until the day you signed up for.
What does "Advent" mean?
Advent is a season leading up to Christmas Day. Advent Calendars mark the days until Christmas. For children, the marking of each day might include a piece of candy or a small toy.
What are some good examples of C# Advent content?
ANY and ALL content that's related to C# is good in my book. The point is to promote the community, our love of C#, and to lift everyone up! However, if you're looking for some good examples, check out the C# Advent 2022 Awards, to see what was popular.
But remember: you don't have to do anything flashy! If you care about C# and you've got something you want to share, I want you to claim a spot!
How long have you been doing this?
The first C# Advent calendar was in 2017.
You're out of open spots! I missed it!
Maybe not! December can be a hectic month, and sometimes people need to drop out. If you want to be on standby, contact me. Being on standby is one of the hardest jobs, since people may drop out with very little notice. But, if you are up to the task, I very much appreciate it, and I'm willing to accomodate or help you in any way I can.
It's the second annual C# Advent 2022 awards! Every year, you all put out such great stuff. Every post is the best!
But, I wanted to do something to recognize the best of the best: the standouts from the latest Advent that have performed above and beyond, and give everyone a chance to revist them and give the Advent one last "hurrah".
Some of these rewards are based on stats like Google Analytics and Reddit upvotes. Some of them are completely arbitrary. I hope you enjoy!
☝ Most Reddit Upvotes
I make sure all of the articles are submitted to /r/csharp and /r/dotnet (with permission of the respective admins). Here are the posts that got the most (combined) upvotes (as of January 5th, 2022):
1. How To Structure Your .NET Solutions by James Hickey - pulled in over 160 upvotes
2. Building Windows Services in .NET 7 by Kevin Griffin - with over 90 upvotes, I'd say there's life left in Windows development
3. Validating .NET Configuration by Chris Ayers - a cool, unique topic gets over 50 upvotes
🖱 Most Clicks from the C# Advent Site
I use Google Analytics on the site. This award pretty much went to the first three participants this time around. Here are the posts that have been most clicked on from the site.
1. Hello from the GitHub Actions: Core .NET SDK by David Pine
2. Web Scraping and Generating PDFs Using C# and .NET by Christopher C. Johnson
3. Validating .NET Configuration by Chris Ayers
🤓 Matt's Favorite
Every post is great and appreciated, but these in particular stuck out to me as especially interesting, fun, and/or useful. Got favorites of your own? Leave a comment below, tweet #csadvent, and write your own C# Advent Awards blog post (and tell me about it, so I can tweet it and link to it)!
1. Generating C# bindings for native libraries by using ChatGPT - ChatGPT is all the rage, but I think this post shows that ChatGPT can be a very efficient and incredibly useful code generation tool.
2. Colorful ASCII Christmas Tree in C# by ChatGPT - This is a much sillier use of ChatGPT, but I love it because of its silliness AND because of how well it ties into Advent in general. AND it is (partially) a blog post written by ChatGPT too. Extraordinarily creative!
3. Advent of Code 2022 via C# - One of a handful of crossovers between the C# Advent and other advents. This post highlights another great advent and shows off C#.
🐣 Best Newcomer
The best content from someone who has never been on the C# Advent before. The criteria is a combination of all the above.
1. Jonathan "J." Tower - J is a long time C# developer community stalwart, and I'm happy to have him on board the C# Advent for the first time with Top-Level Statements in C#
2. Matthias Jost - Filled in for a dropped day with a great post that everyone can enjoy: How Do I Follow My Favourite .NET Blogs?
3. Brendan Enrick - Another long-time community contributor joins with 11 Ways of Making Your C# Harder to Use
👴 Best Veteran
Same as above, except for those who have posted to the C# Advent before.
1. Matt Eland - Thank you for your TWO contributions this year (one to fill in for a dropped day) - Text Classification in C# with ML.NET 2.0 and Interactive C# with Polyglot Notebooks
2. Jonathan Danylko - Has been a part of C# Advent since the beginning, thank you for Creating Multi-Tier Subscriptions using C#
3. Barret Blake - Another long time Advent contributor brings us Turning Any JSON API Into An App
Honorable Mention to Baskar Rao for being a veteran of every year AND having the most total contributions (seven - he contributed twice in 2017)
Thank you to everyone who participated! I've already started planning enhancements for next year. Be sure to watch mgroves on Twitter, the C# Advent site, and this very blog for announcements when the calendar gets toward the last third.
Thank you Smashing Magazine for featuring the Advent Calendars For Web Designers And Developers (2022 Edition) round-up.
Thank you Sergey Tihon for the inspiration.
A special extra thanks to Calvin Allen, who does a lot of behind-the-scenes work on C# Advent (including the domain name, LinkedIn, the CsAdvent twitter account, testing, and much more) even while juggling the arrival of a new family member. Congratulations and thank you!
I’ve written about How I use Fluent Migrator and Lessons learned about Fluent Migrator. I like using Fluent Migrator when I worked with relational databases.
However, I spend most of my time working with the NoSQL document database Couchbase, these days. If the idea of Fluent Migrator for Couchbase sounds interesting, read on!
What are database migrations?
Database migrations (not to be confused with data migrations) are a series of scripts/definitions that build the structure of a database. For instance, the first script could create 15 tables. The next script might alter a table, or add a 16th table. And so on.
Why are they important?
Having database migrations are important because they make sure anyone interacting with the database is on the same page, whether they’re working on a local database, test database, staging database, production, etc. Migrations can be part of the CI/CD process, as well.
What good is that for NoSQL?
If you’re not familiar with NoSQL, you might think that migrations wouldn’t make any sense. However, NoSQL databases (especially document databases), while flexible, are not devoid of structure. For instance, in place of Database/Schema/Table/Row, Couchbase has the concepts of Bucket/Scope/Collection/Document that roughly correspond.
It’s true that a NoSQL migration would not have as much predefined detail (there’s nowhere to specify column names and data types, for instance), but the benefits of migrations can still help developers working with Couchbase.
Introducing NoSqlMigrator for Couchbase
I’ve created a brand new project called NoSqlMigrator, to offer the same style of migration as Fluent Migrator.
Important notes:
-
This is not a fork or plugin of Fluent Migrator. It’s a completely separate project.
-
This is not an official Couchbase, Inc product. It’s just me creating it as an open source, community project.
-
It’s very much a WIP/alpha release. Please leave suggestions, criticisms, PRs, and issues!
Setting up migrations in C#
The process is very similar to Fluent Migrator.
-
Create a project that will contain your migration classes (you technically don’t have to, but I recommend it).
-
Add NoSqlMigrator from NuGet to that project.
-
Create classes that inherit from
Migrate
base class. Define anUp
andDown
. Add aMigration
attribute and give it a number (typically sequential). -
When you’re ready to run migrations, you can use the CLI migration runner, available as a release on GitHub, or you can use the
MigrationRunner
class, and run the migrations from whatever code you like. (I recommend the CLI).
Currently, NoSqlMigrator only supports Couchbase. Unlike the relational world, there is a lot of variance in structure and naming in the NoSQL world, so adding support for other NoSQL databases might be awkward (But I won’t rule that out for the far future).
Creating your first migration
Here’s an example of a migration that creates a scope and a collection (a bucket must already exist) when going "Up". When going down, the scope is deleted (along with any collections in it).
[Migration(1)]
public class Migration001_CreateInitialScopeAndCollection : Migrate
{
public override void Up()
{
Create.Scope("myScope")
.WithCollection("myCollection1");
}
public override void Down()
{
Delete.Scope("myScope");
}
}
If you are new to migrations, the Down
can sometimes be tricky. Not everything can be neatly "downed". However, I find that I tend to only use Down during development, and rarely does it execute in test/integration/production. But it is possible, so do your best when writing Down
, but don’t sweat it if you can’t get it perfect.
Running the migration
Here’s an example of using the command line to run a migration:
> NoSqlMigrator.Runner.exe MyMigrations.dll couchbase://localhost Administrator password myBucketName
That will run all the Up
implementations (that haven’t already been run: it keeps track with a special document in Couchbase).
You can also specify a limit (e.g. run all migrations up to/down from #5) and you can specify a direction (up/down). Here’s an example of running Up (explicitly) with a limit of 5:
> NoSqlMigrator.Runner.exe MyMigrations.dll couchbase://localhost Administrator password myBucketName -l 5 -d Up
More features for NoSQL migrations
Here are all the commands currently available:
-
Create.Scope
-
Create.Collection
-
Create.Index
-
Delete.Scope
-
Delete.Collection
-
Delete.FromCollection
-
Delete.Index
-
Insert.IntoCollection
-
Execute.Sql
-
Update.Document
-
Update.Collection
I’m working on a few more, and I have some GitHub issues listing commands that I plan to add. But if you can think of any others, please create an issue!
Tips and Conclusion
Many of the Lessons learned still apply to NoSqlMigrator.
In that post, I mention Octopus, but imagine any CI/CD/deployment tool of your choice in its place (e.g. Jenkins, GitHub Actions, etc).
I think NoSqlMigrator can be a very handy tool for keeping databases in sync with your team, checking knowledge into source control, and providing a quick way to get a minimum database structure built, to make your day of coding a little easier.
Please give it a try in your own project! If you’ve not used Couchbase, check out a free trial of Couchbase Capella DBaaS.