Introduction
Click this link to watch an introductory video on Marten.
What is Marten?
Marten is a library distributed by Nuget that allows .Net developers to use the Postgresql database as both a document database and a full-featured event store -- with the document database features being the out of the box mechanism for projected "read side" views of your events. There is absolutely nothing else to install in your application other than the Nuget or process to run other than Postgresql itself. Marten was made possible by the unique JSONB support first introduced in Postgresql 9.4.
Marten was originally built to replace Raven Db inside a very large web application that was suffering stability and performance issues. The project name Marten came from a quick Google search one day for "what are the natural predators of ravens?" -- which led to us to use the marten as our project codename and avatar.
The Marten project was publicly announced in late 2015 and quickly gained a solid community of interested developers. An event sourcing feature set was added early on, which helped Marten attract much more interest. Marten first went into a production system in 2016 and has been going strong ever since. The V4 release in 2021 marks a massive overhaul of Marten's internals and new functionality requested by our users to better position Marten for the future.
.NET version compatibility
Marten aligns with the .NET Core Support Lifecycle to determine platform compatibility.
4.xx targets netstandard2.0
& net5.0
and is compatible with .NET Core 2.x
, .NET Core 3.x
and .NET 5+
.
INFO
.NET Framework support was dropped as part of the v4 release, if you require .NET Framework support, please use the latest Marten 3.xx release.
Marten Quickstart
INFO
There's a very small sample project in the Marten codebase that shows the mechanics for wiring Marten into a .Net Core application.
Following the common .Net idiom, Marten supplies extension methods to quickly integrate Marten into any .Net Core application that uses the IServiceCollection
abstractions to register IoC services.
In the Startup.ConfigureServices()
method of your .Net Core application (or you can use IHostBuilder.ConfigureServices()
as well) make a call to AddMarten()
to register Marten services like so:
public class Startup
{
public IConfiguration Configuration { get; }
public IHostEnvironment Environment { get; }
public Startup(IConfiguration configuration, IHostEnvironment environment)
{
Configuration = configuration;
Environment = environment;
}
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
// This is the absolute, simplest way to integrate Marten into your
// .Net Core application with Marten's default configuration
services.AddMarten(options =>
{
// Establish the connection string to your Marten database
options.Connection(Configuration.GetConnectionString("Marten"));
// If we're running in development mode, let Marten just take care
// of all necessary schema building and patching behind the scenes
if (Environment.IsDevelopment())
{
options.AutoCreateSchemaObjects = AutoCreate.All;
}
});
}
// and other methods we don't care about right now...
See integrating Marten in .NET Core applications for more information and options about this integration.
Also see the blog post Marten, the Generic Host Builder in .Net Core, and why this could be the golden age for OSS in .Net for more background about how Marten is fully embracing the generic host in .Net.
Working with Documents
Now, for your first document type, let's represent the users in our system:
public class User
{
public Guid Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public bool Internal { get; set; }
public string UserName { get; set; }
public string Department { get; set; }
}
For more information on document identity, see identity.
And now that we've got a PostgreSQL schema and an IDocumentStore
variable called store
, let's start persisting and loading user documents:
// Open a session for querying, loading, and
// updating documents
using (var session = store.LightweightSession())
{
var user = new User { FirstName = "Han", LastName = "Solo" };
session.Store(user);
await session.SaveChangesAsync();
}
// Open a session for querying, loading, and
// updating documents with a backing "Identity Map"
using (var session = store.QuerySession())
{
var existing = await session
.Query<User>()
.SingleAsync(x => x.FirstName == "Han" && x.LastName == "Solo");
}
Now that we've got a document store, we can use that to create a new IQuerySession
object just for querying or loading documents from the database:
using (var session = store.QuerySession())
{
var internalUsers = session
.Query<User>().Where(x => x.Internal).ToArray();
}
For more information on the query support within Marten, check document querying
There is a lot more capabilities than what we're showing here, so head on over to the table of contents on the sidebar to see what else Marten offers.
Working with Events
Please check Event Store quick start