Skip to content

Commit aa77ced

Browse files
committed
updated readme files for 0.8.0 release
1 parent 0995ced commit aa77ced

File tree

2 files changed

+26
-17
lines changed

2 files changed

+26
-17
lines changed

Code/src/Synnotech.Migrations.RavenDB/readme.md

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
[![Synnotech Logo](https://github.com/Synnotech-AG/Synnotech.Migrations/raw/main/synnotech-large-logo.png)](https://www.synnotech.de/)
66

77
[![License](https://img.shields.io/badge/License-MIT-green.svg?style=for-the-badge)](https://github.com/Synnotech-AG/Synnotech.Migrations/blob/main/LICENSE)
8-
[![NuGet](https://img.shields.io/badge/NuGet-0.7.0-blue.svg?style=for-the-badge)](https://www.nuget.org/packages/Synnotech.Migrations.RavenDB/)
8+
[![NuGet](https://img.shields.io/badge/NuGet-0.8.0-blue.svg?style=for-the-badge)](https://www.nuget.org/packages/Synnotech.Migrations.RavenDB/)
99

1010
# How to Install
1111

1212
Synnotech.Migrations.RavenDB is compiled against [.NET Standard 2.0 and 2.1](https://docs.microsoft.com/en-us/dotnet/standard/net-standard) and thus supports all major plattforms like .NET 5, .NET Core, .NET Framework 4.6.1 or newer, Mono, Xamarin, UWP, or Unity.
1313

1414
Synnotech.Migrations.RavenDB is available as a [NuGet package](https://www.nuget.org/packages/Synnotech.Migrations.RavenDB/) and can be installed via:
1515

16-
- **Package Reference in csproj**: `<PackageReference Include="Synnotech.Migrations.RavenDB" Version="0.7.0" />`
16+
- **Package Reference in csproj**: `<PackageReference Include="Synnotech.Migrations.RavenDB" Version="0.8.0" />`
1717
- **dotnet CLI**: `dotnet add package Synnotech.Migrations.RavenDB`
1818
- **Visual Studio Package Manager Console**: `Install-Package Synnotech.Migrations.RavenDB`
1919

@@ -23,7 +23,7 @@ If you want to run with the default setup, registration is pretty easy. Synnotec
2323

2424
## Set Up in ASP.NET Core Apps
2525

26-
If you write an ASP.NET Core app, you can simply call `AddSynnotechMigration` in `Startup.ConfigureService`:
26+
If you write an ASP.NET Core app, you can simply call `AddSynnotechMigrations` in `Startup.ConfigureService`:
2727

2828
```csharp
2929
public sealed class Startup
@@ -49,20 +49,25 @@ public sealed class Startup
4949
}
5050
```
5151

52-
`AddSynnotechMigrations` registers the `SessionFactory` as well as the `MigrationEngine` with a transient lifetime. If there is not already a registration for `IAsyncDocumentSession`, one will be created as well with a transient lifetime. Take a look at the [ServiceCollectionExtensions](https://github.com/Synnotech-AG/Synnotech.Migrations/blob/main/Code/src/Synnotech.Migrations.RavenDB/ServiceCollectionExtensions.cs) class to see what is going on exactly.
52+
`AddSynnotechMigrations` registers the `MigrationEngine`, all required services, and your migrations (classes that derive from `Migration` directly or indirectly) with a transient lifetime. Take a look at the [ServiceCollectionExtensions](https://github.com/Synnotech-AG/Synnotech.Migrations/blob/main/Code/src/Synnotech.Migrations.RavenDB/ServiceCollectionExtensions.cs) class to see what is going on exactly.
5353

5454
Please ensure that a registration for `IDocumentStore` is already present in the DI container. You can use [Synnotech.RavenDB](https://github.com/Synnotech-AG/Synnotech.RavenDB) to do that.
5555

5656
We suggest that you run your migrations at the beginning of `Startup.Configure`, so that the target database is up to date every time the web app starts. Of course, you are not limited to that - you could e.g. create a dedicated controller action that executes migrations.
5757

5858
## Setup in Other Apps
5959

60-
To instantiate the `MigrationEngine`, you need to provide an `ISessionFactory<MigrationSession, MigrationInfo>` to the constructor. This interface is implemented by `SessionFactory`. `SessionFactory` itself requires an instance of RavenDB's `IDocumentStore`. With Pure DI, you can create a migration engine instance this way:
60+
To instantiate the `MigrationEngine`, you need to provide the following services:
6161

62-
```csharp
62+
- `ISessionFactory<MigrationInfo, Migration, IAsyncDocumentSession>`: the default implementation is `SessionFactory`
63+
- `IMigrationFactory<Migration>`: there are two options here by default - `MicrosoftDependencyInjectionMigrationFactory<TMigration>` uses your DI container (via `IServiceProvider`) to instantiate migrations. If you use this option, all your migrations must be registered against the DI container (you can use the [AddMigrationTypes](https://github.com/Synnotech-AG/Synnotech.Migrations/blob/main/Code/src/Synnotech.Migrations.Core/Migrations.cs#L27) extension method for that). `ActivatorMigrationFactory<TMigration>` uses `Activator.CreateInstance` to call the default constructor of a migration. You can also derive from `BaseMigrationFactory<TMigration>` to implement your own factory (e.g. when you want to adapt for your custom DI container).
64+
- `Func<Migration, DateTime, MigrationInfo>`: this delegate is used to instantiate migration infos from migrations and a timestamp.
65+
66+
```csharp
6367
IDocumentStore store = InitializeDocumentStore(); // Configures connection to RavenDB server
6468
var sessionFactory = new SessionFactory(store);
65-
var migrationEngine = new MigrationEngine(sessionFactory);
69+
var migrationFactory = new ActivatorMigrationFactory<Migration>();
70+
var migrationEngine = new MigrationEngine(sessionFactory, migrationFactory, MigrationInfo.Create);
6671
```
6772

6873
If you use a DI container, you could register the types similar to the following pseudo code:
@@ -71,12 +76,16 @@ If you use a DI container, you could register the types similar to the following
7176
IDocumentStore store = InitializeDocumentStore(); // Configures connection to RavenDB server
7277
container.RegisterSingleton(store)
7378
.RegisterTransient<SessionFactory>()
74-
.RegisterTransient(c => new MigrationEngine(c.Resolve<SessionFactory>()))
79+
.RegisterTransient<ActivatorMigrationFactory<Migration>>()
80+
.RegisterSingleton<Func<Migration, DateTime, MigrationInfo>>(MigrationInfo.Create)
81+
.RegisterTransient(c => new MigrationEngine(c.Resolve<SessionFactory>(),
82+
c.Resolve<ActivatorMigrationFactory<Migration>>(),
83+
c.Resolve<Func<Migration, DateTime, MigrationInfo>>()));
7584
```
7685

7786
## Writing Migrations
7887

79-
A migration is a `public` class that derives from the `Migration` base class and is decorated with the `MigrationVersion` attribute. It has a single method called `ApplyAsync` where you receive a `MigrationSession` that you can use to manipulate the target database.
88+
A migration is a `public` class that derives from the `Migration` base class and is decorated with the `MigrationVersion` attribute. It has a single method called `ApplyAsync` where you receive RavenDB's `IAsyncDocumentSession` and a `CancellationToken` that you can use to manipulate the target database.
8089

8190
A typical migration might look like this:
8291

@@ -91,12 +100,11 @@ namespace MyRavenDBAccessLayer
91100
[MigrationVersion("1.0.0")]
92101
public sealed class InitialMasterData : Migration
93102
{
94-
public override async Task ApplyAsync(MigrationSession context)
103+
public override async Task ApplyAsync(IAsyncDocumentSession session)
95104
{
96-
IAsyncDocumentSession session = context.Session;
97105
var masterData = MasterData.GetInitialMasterData();
98106

99-
foreach(var item in masterData)
107+
foreach (var item in masterData)
100108
{
101109
await session.StoreAsync(item);
102110
}
@@ -108,9 +116,10 @@ namespace MyRavenDBAccessLayer
108116
When writing migrations, keep the following things in mind:
109117

110118
1. You don't need to call `session.SaveChangesAsync` - the migration engine will do that for you.
111-
1. Every migration gets a fresh `MigrationSession` instance. `WaitForIndexesAfterSaveChanges` is activated by default, so you can be sure that you can query data that was inserted in previous migrations.
119+
1. Every migration gets a fresh session instance. `WaitForIndexesAfterSaveChanges` is activated by default, so you can be sure that you can query data that was inserted in previous migrations.
112120
1. Also, you do not need to add `MigrationInfo` instances manually to the database, the migration engine will do that for you.
113121
1. The `MigrationVersion` uses the default `System.Version` class internally to determine the version. We suggest you use [Semantic Versioning](https://semver.org/) for your migrations.
122+
1. If you use the default setup, or resolve your migrations via a DI container, you can incorporate Dependency Injection in your migration classes (usually via Constructor Injection). If your migration implements `IAsyncDisposable` or `IDisposable`, the migration engine will dispose them after execution.
114123
1. We encourage you to organize your migations in a dedicated subfolder of your RavenDB data access folder / project (see picture below).
115124
1. We suggest that you create a dedicated integration test that tries to apply all migrations at once to a fresh RavenDB database, thus you can be sure everything works correctly before rolling out your software.
116125

@@ -123,7 +132,7 @@ When writing migrations, keep the following things in mind:
123132
The migration engine offers you three methods to apply migrations to the target database:
124133

125134
1. `MigrateAsync` does all in one go: it first checks the target system and tries to retrieve information about the latest applied migration. Based on this, it then determines which migrations need to be applied and executes them against the target database.
126-
2. `GenerateMigrationPlanAsync` only checks the target database and retrieves information about the latest applied migration. It also determines which migrations need to be applied and returns both information. This is useful if the calling code wants to know if there are any pending migrations and then ask the user to confirm the database changes.
135+
2. `GetPlanForNewMigrationsAsync` only checks the target database and retrieves information about the latest applied migration. It also determines which migrations need to be applied and returns both information. This is useful if the calling code wants to know if there are any pending migrations and then ask the user to confirm the database changes.
127136
3. `ApplyMigrationsAsync` takes a list of migrations and applies them to the target database. Is often used in combination with `GenerateMigrationPlanAsync`.
128137

129138
In most apps, we suggest that you simply use `MigrateAsync` at application start to keep the database up-to-date. The two other methods are typically used if you have a dedicated Export-to-Database functionality where the user can agree or disagree with applying the latest migrations.
@@ -139,7 +148,7 @@ public static class RavenDbExtensions
139148
{
140149
public static async Task MigrateAsync(this MigrationEngine migrationEngine, ILogger logger)
141150
{
142-
var summary = await migrationEngine.MigrateAsync(typeof(RavenDbExtensions).Assembly, DateTime.UtcNow);
151+
var summary = await migrationEngine.MigrateAsync();
143152

144153
// First we try to log all applied migrations of this run
145154
if (summary.TryGetAppliedMigrations(out var appliedMigrations))

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
[![Synnotech Logo](synnotech-large-logo.png)](https://www.synnotech.de/)
66

77
[![License](https://img.shields.io/badge/License-MIT-green.svg?style=for-the-badge)](https://github.com/Synnotech-AG/Synnotech.Migrations/blob/main/LICENSE)
8-
[![NuGet](https://img.shields.io/badge/NuGet-0.7.0-blue.svg?style=for-the-badge)](https://www.nuget.org/packages?q=Synnotech.Migrations)
8+
[![NuGet](https://img.shields.io/badge/NuGet-0.8.0-blue.svg?style=for-the-badge)](https://www.nuget.org/packages?q=Synnotech.Migrations)
99

1010
When starting a new project, do you always spent too much time on how you can migrate your database? Do you want a migration mechanism that is independent of any persistence technology, like ORMs for relational databases? Worry no more because **Synnotech.Migrations** offers just that! Our generic migration engine is written in such a way so that you can easily adapt it to your own data access layer, no matter the technology: relational databases with and without ORMs, document or graph databases, the file system, or web services - the possibilities are endless.
1111

@@ -26,7 +26,7 @@ Please visit the corresponding pages for further documentation.
2626

2727
## Supported Frameworks
2828

29-
**Synnotech.Migrations** is build for .NET Standard 2.0, so you can use it on [all platforms that support it](https://docs.microsoft.com/en-us/dotnet/standard/net-standard), e.g. like:
29+
**Synnotech.Migrations** is build for .NET Standard 2.0 and .NET Standard 2.1, so you can use it on [all platforms that support it](https://docs.microsoft.com/en-us/dotnet/standard/net-standard), e.g. like:
3030

3131
- .NET 5 or newer
3232
- .NET Core 2.0 or newer

0 commit comments

Comments
 (0)