-
Notifications
You must be signed in to change notification settings - Fork 32
Migrate Extension module from the Platform 2.0 to 3.0 version
This article describes how to migrate existing extension module from 2.0 to 3.0 version.
NOTE: A sample module source code can be found here: https://github.com/VirtoCommerce/vc-platform-core/tree/dev/Modules/vc-module-customer/samples/VirtoCommerce.CustomerSampleModule.Web
For example, have project with name Cart2Module.Web.csproj for CartModule.
- Create a new branch with name: migrate-to-v3 then switch to the branch.
- Then create a new solution for extension module if not exists.
- Then need to migrate the project from ASP.NET to ASP.NET Core.
please read this article https://docs.microsoft.com/en-us/aspnet/core/migration/proper-to-2x
Need to make changes in the Core/Data/Web extension projects Cart2Module.XXX.csproj
- Change xml signature to
<Project Sdk="Microsoft.NET.Sdk"> </Project>
- Then add TargetFramework, at the moment netcoreapp2.2 is latest as PropertyGroup inside Project
<TargetFramework>netcoreapp2.2</TargetFramework>
- Add references NuGet packages(if you have) and dependencies from module.manifest as ItemGroup
<ProjectReference Include="..\..\VirtoCommerce.CartModule.Core\VirtoCommerce.CartModule.Core.csproj" />
<ProjectReference Include="..\..\VirtoCommerce.CartModule.Data\VirtoCommerce.CartModule.Data.csproj" />
- Need to add Cart2DbContext inheritance from CartDbContext
- Add overriding OnModelCreating method
- Then need to map all extended models. If there are classes Cart2Entity.cs and Cart2 with signature:
public class Cart2 : ShoppingCart
{
public string CartType { get; set; }
}
Then need to add mapping to modelBuilder
modelBuilder.Entity<Cart2Entity>();
NOTE: A factory for creating derived Microsoft.EntityFrameworkCore.DbContext instances.
- Create a class DesignTimeDbContextFactory.cs
- Inherite from IDesignTimeDbContextFactory
- Add CreateDbContext method with Cart2DbContext, example code can copy from https://github.com/VirtoCommerce/vc-platform-core/blob/master/Modules/vc-module-customer/samples/VirtoCommerce.CustomerSampleModule.Web/Repositories/DesignTimeDbContextFactory.cs#L8
- Change connection string for database in UseSqlServer method. It need for migration.
- The class have to derive from CartRepository and have constructor with the new Core2DbContext dependency
- Add DbSet Cart2 to access data
public IQueryable<Cart2Entity> Cart2 => DbContext.Set<Cart2Entity>();
- Remove OnModelCreating method
- Add overriding methods, if need to add some logic
- Remove old migrations in the folder Migrations which generated for v. 2.0
- Create a migration with name InitialCart2, you could run a command from Package Manager Console
Add-Migration InitialCart2 -Context VirtoCommerce.Cart2Module.Web.Repositories.Cart2DbContext -StartupProject VirtoCommerce.Cart2Module.Web -Verbose -OutputDir Migrations
- then need to remove the lines which depends CartDbContext(like Tables, FK, PK, Index)
- If the entity Cart2 extend with a new property CartType, then need to add code:
migrationBuilder.AddColumn<string>(name: "CartType", table: "Cart", maxLength: 128, nullable: true);
and add line:
migrationBuilder.AddColumn<string>(name: "Discriminator", table: "Cart", nullable: false, maxLength: 128, defaultValue: "Cart2Entity");
look at https://docs.microsoft.com/en-us/ef/core/modeling/relational/inheritance example https://github.com/VirtoCommerce/vc-platform-core/raw/master/Modules/vc-module-orders/samples/VirtoCommerce.OrdersModule2.Web/Migrations/20180724064542_InitialOrders2.cs
- Need to create migration with name UpdateCart2V2 and rename the migration file name to 20000000000000_UpdateCart2V2
- Add SQL Insert command to 20000000000000_UpdateCart2V2
and rename migration name to InitialCart2 in sql-script.
- Also need to rename UpdateCart2V2.Designer to 20000000000000_ UpdateCart2V2.Designer and rename MigrationAttribute
If there are extension settings/permission/localizations in module.manifest, need to do:
- Create a class ModuleConstants.cs which contains settings, permissions in VirtoCommerce.Cart2Module.Web project
- Settings move to ModuleConstants, for example have Cart2.Search.Setting and the code will be:
public static class Settings
{
public static class General
{
public static SettingDescriptor Cart2Setting = new SettingDescriptor
{
Name = "VirtoCommerce.Cart2.Search.Cart2Setting",
GroupName = "Cart2|Search",
ValueType = SettingValueType.ShortText,
IsDictionary = true,
};
public static IEnumerable<SettingDescriptor> AllSettings
{
get
{
yield return Cart2Setting;
}
}
}
public static IEnumerable<SettingDescriptor> AllSettings
{
get
{
return General.AllSettings;
}
}
}
and localization of name and description need to add localization file (read down)
- Permissions also move to ModuleConstants, have permission for searching in Cart, then the code will be:
public static class Security
{
public static class Permissions
{
public const string Cart2SearchAccess = "cart2:search:access";
public static string[] AllPermissions = { Cart2SearchAccess };
}
}
- Localization of settings and permissions move to VirtoCommerce.Cart2Module.Web/Localizations/en.VirtoCommerce.Cart2.json
- Need to change inheritance to interface IModule , then add implementation methods: Initialize, PostInitialize, Uninstall and property ModuleInfo
- Add all dependency injections to Initialize method, like as Cart2DbContext, Cart2RepositoryImpl
- Register settings using interface ISettingsRegistrar in PostInitialize method
var settingsRegistrar = appBuilder.ApplicationServices.GetRequiredService<ISettingsRegistrar>();
settingsRegistrar.RegisterSettings(ModuleConstants.Settings.AllSettings, ModuleInfo.Id);
- Register permissions using interface IPermissionsRegistrar in PostInitialize method
var permissionsProvider = appBuilder.ApplicationServices.GetRequiredService<IPermissionsRegistrar>();
permissionsProvider.RegisterPermissions(ModuleConstants.Security.Permissions.AllPermissions.Select(x => new Permission() { GroupName = "Cart2", Name = x }).ToArray());
- Override type Cart2 in AbstractFactory, like this:
AbstractTypeFactory<Cart>.OverrideType<Cart, Cart2>().MapToType<Cart2Entity>();
AbstractTypeFactory<CartEntity>.OverrideType<CartEntity, Cart2Entity>();
- Add three methods MigrateIfNotApplied, EnsureCreated, Migrate into PostInitialize method, need for insure creating migration
using (var serviceScope = appBuilder.ApplicationServices.CreateScope())
{
var dbContext = serviceScope.ServiceProvider.GetRequiredService<CartDbContext>();
dbContext.Database.MigrateIfNotApplied(MigrationName.GetUpdateV2MigrationName(ModuleInfo.Id));
dbContext.Database.EnsureCreated();
dbContext.Database.Migrate();
}
NOTE: Extension MigrateIfNotApplied need for backward compatibility v.2.0. The extension allows don't generate initial migration, because there are already tables in the DataBase.
If have extension scripts, then need to do:
- add webpack packages (package.json, webpack.config.js) to VirtoCommerce.Cart2Module.Web
these files: https://github.com/VirtoCommerce/vc-platform-core/blob/master/Modules/vc-module-customer/VirtoCommerce.CustomerModule.Web/package.json https://github.com/VirtoCommerce/vc-platform-core/blob/master/Modules/vc-module-customer/VirtoCommerce.CustomerModule.Web/webpack.config.js
- change namespace in webpack.config.js (line 15)
- build and pack js scripts and css for Cart2Module
npm run webpack:dev
- Check what all your extensions works with the new platform without exceptions and as expected with initial empty data