Bui l d i ng gr8 - Umbraco Codegarden 2019 · 2019-06-17 · KEKO. W hat w ill w e c ove r Summa ry...
Transcript of Bui l d i ng gr8 - Umbraco Codegarden 2019 · 2019-06-17 · KEKO. W hat w ill w e c ove r Summa ry...
Building gr8packages
1 / 59
HelloDave Woestenborghs42 years oldFrom BelgiumWorks at We Are YouUsing Umbraco since 20083x 4x MVP
2 / 59
ActiveCommunitymember
Active forum memberCore contributorPackage developerMember of the PR teamMember of the BUUG boardPart of 24 days in Umbraco
3 / 59
Looking forauthors
Jan Skovgaard Chriztian Steinmeier
4 / 59
What willwe cover
5 / 59
What willwe cover
Summary V8 changes
5 / 59
What willwe cover
Summary V8 changesWhat de�nes a greatpackage
5 / 59
What willwe cover
Summary V8 changesWhat de�nes a greatpackageMigrating packages from V7
5 / 59
What willwe cover
Summary V8 changesWhat de�nes a greatpackageMigrating packages from V7Angular changes
5 / 59
What willwe cover
Summary V8 changesWhat de�nes a greatpackageMigrating packages from V7Angular changesC# changes
5 / 59
V8
6 / 59
7 / 59
V8 Summarized
8 / 59
V8 SummarizedRemoval of hartvig-code
8 / 59
V8 SummarizedRemoval of hartvig-code
hartvig-code : codewritten by someone who
can't code. - Stephane Gay
8 / 59
Codecleanup
9 / 59
Codecleanup
V-latest all dependencies
9 / 59
Codecleanup
V-latest all dependenciesRemoval of webformssupport
9 / 59
Codecleanup
V-latest all dependenciesRemoval of webformssupportRemoval of XSLT
9 / 59
Codecleanup
V-latest all dependenciesRemoval of webformssupportRemoval of XSLTRemoval of legacy API's
9 / 59
Codecleanup
V-latest all dependenciesRemoval of webformssupportRemoval of XSLTRemoval of legacy API'sNuCache
9 / 59
Codecleanup
V-latest all dependenciesRemoval of webformssupportRemoval of XSLTRemoval of legacy API'sNuCacheDependency injection
9 / 59
Codecleanup
V-latest all dependenciesRemoval of webformssupportRemoval of XSLTRemoval of legacy API'sNuCacheDependency injectionRename all the things �
9 / 59
NewFeatures
10 / 59
NewFeatures
Variants aka multilanguage
10 / 59
NewFeatures
Variants aka multilanguageContent apps
10 / 59
NewFeatures
Variants aka multilanguageContent appsIn�nite editing
10 / 59
NewFeatures
Variants aka multilanguageContent appsIn�nite editingNew backof�ce UI
10 / 59
Whatmakes a
greatpackage?
11 / 59
12 / 59
1 Source code available
12 / 59
1 Source code available2 Documentation
12 / 59
1 Source code available2 Documentation3 A way to contact owner
12 / 59
1 Source code available2 Documentation3 A way to contact owner4 Actively maintenained
12 / 59
1 Source code available2 Documentation3 A way to contact owner4 Actively maintenained5 Open for contribution
12 / 59
1 Source code available2 Documentation3 A way to contact owner4 Actively maintenained5 Open for contribution6 Roadmap
12 / 59
1 Source code available2 Documentation3 A way to contact owner4 Actively maintenained5 Open for contribution6 Roadmap7 Nuget option available
12 / 59
Migratingpackages
to V8
13 / 59
Migration options
14 / 59
Migration options
1 Ignore V8
14 / 59
Migration options
1 Ignore V82 Migrate V8, ignore V7
14 / 59
Migration options
1 Ignore V82 Migrate V8, ignore V73 A version for V7 & V8
14 / 59
Migration options
1 Ignore V82 Migrate V8, ignore V73 A version for V7 & V84 A hybrid package supporting both
14 / 59
Migration options
1 Ignore V82 Migrate V8, ignore V73 A version for V7 & V84 A hybrid package supporting both5 A completely new package for V8
14 / 59
Migration options
by Andy Butland
1 Ignore V82 Migrate V8, ignore V73 A version for V7 & V84 A hybrid package supporting both5 A completely new package for V8
Skrift article
14 / 59
15 / 59
Migration struggles
16 / 59
Migration strugglesThey moved my �
16 / 59
Migration strugglesThey moved my �Classes got renamed
16 / 59
Migration strugglesThey moved my �Classes got renamedCore concepts got changed
16 / 59
Migration strugglesThey moved my �Classes got renamedCore concepts got changedDocumentation "not ready"
16 / 59
Migration strugglesThey moved my �Classes got renamedCore concepts got changedDocumentation "not ready"No migration guide
16 / 59
Migration strugglesThey moved my �Classes got renamedCore concepts got changedDocumentation "not ready"No migration guideInformation scattered over HQ member personal blogs
16 / 59
Open, the source is.
Use it, you must
17 / 59
Creatingpropertyeditors
18 / 59
Property editor changes
19 / 59
Property editor changes
ANGULAR
dialogServiceremoved
19 / 59
Property editor changes
ANGULAR
dialogServiceremoved
C#
Registrationclasses changed
19 / 59
Property editor changes
ANGULAR
dialogServiceremoved
C#
Registrationclasses changed
C#
Converterclasses changed
19 / 59
Bye bye dialogservice
Hello editorService
20 / 59
Bye bye dialogservice
Hello editorServiceDialogService deprecated since 7.4, in favor of the
directiveumb-dialog
20 / 59
Bye bye dialogservice
Hello editorServiceDialogService deprecated since 7.4, in favor of the
directive is a application-wide service for
handling in�nite editing introduced in V8
umb-dialogEditorService
20 / 59
Bye bye dialogservice
Hello editorServiceDialogService deprecated since 7.4, in favor of the
directive is a application-wide service for
handling in�nite editing introduced in V8A lot of built-in dialogues (content, media, etc...)
umb-dialogEditorService
20 / 59
Bye bye dialogservice
Hello editorServiceDialogService deprecated since 7.4, in favor of the
directive is a application-wide service for
handling in�nite editing introduced in V8A lot of built-in dialogues (content, media, etc...)Custom views possible
umb-dialogEditorService
20 / 59
Editor service view example<div ng-controller="My.MediaPickerController as vm"> <button type="button" ng-click="vm.openMediaPicker()"> Open </button></div>
21 / 59
Editor service controller examplefunction MediaPickerController(editorService) { var vm = this; vm.openMediaPicker = openMediaPicker; function openMediaPicker() { var mediaPickerOptions = { multiPicker: true, submit: function(model) { editorService.close(); }, close: function() { editorService.close(); } }; editorService.mediaPicker(mediaPickerOptions); }}
22 / 59
Editor service controller example
function MediaPickerController(editorService) { var vm = this; vm.openMediaPicker = openMediaPicker; function openMediaPicker() { var mediaPickerOptions = { multiPicker: true, submit: function(model) { editorService.close(); }, close: function() { editorService.close(); } }; editorService.mediaPicker(mediaPickerOptions); }}
Inject the service in your controller
22 / 59
Editor service controller example
function openMediaPicker() { var mediaPickerOptions = { multiPicker: true, submit: function(model) { editorService.close(); }, close: function() { editorService.close(); } }; editorService.mediaPicker(mediaPickerOptions); }
function MediaPickerController(editorService) { var vm = this; vm.openMediaPicker = openMediaPicker;
}
Set the dialogue options and open dialog
22 / 59
Registering property editors
23 / 59
Registering property editors
For simple editors => package.manifest
23 / 59
Registering property editors
For simple editors => For more advanced editors => C#
package.manifest
23 / 59
Registering property editors
For simple editors => For more advanced editors => C#Gives more control of con�g, data, validation
package.manifest
23 / 59
C# - What changed
V7 V8
Prevalues PreValueEditor Con�gurationEditor<T>
24 / 59
C# - What changed
V7 V8
Prevalues PreValueEditor Con�gurationEditor<T>
ValueEditor PropertyValueEditor DataValueEditor
24 / 59
C# - What changed
V7 V8
Prevalues PreValueEditor Con�gurationEditor<T>
ValueEditor PropertyValueEditor DataValueEditor
Editor PropertyEditor DataEditor
24 / 59
Con�gurationpublic class NestedContentConfiguration{ [ConfigurationField("minItems", "Min Items", "number", Description = "Set the minimum number of items allowed.")] public int? MinItems { get; set; }} public class NestedContentConfigurationEditor : ConfigurationEditor<NestedContentConfiguration>{ public override object DefaultConfigurationObject { get; } = new NestedContentConfiguration();}
25 / 59
Con�guration
public class NestedContentConfiguration{ [ConfigurationField("minItems", "Min Items", "number", Description = "Set the minimum number of items allowed.") public int? MinItems { get; set; }} public class NestedContentConfigurationEditor : ConfigurationEditor<NestedContentConfiguration>{ public override object DefaultConfigurationObject { get; } = new NestedContentConfiguration();}
Con�guration class
25 / 59
Con�guration
public class NestedContentConfigurationEditor : ConfigurationEditor<NestedContentConfiguration>
public class NestedContentConfiguration{ [ConfigurationField("minItems", "Min Items", "number", Description = "Set the minimum number of items allowed.")] public int? MinItems { get; set; }}
{ public override object DefaultConfigurationObject { get; } = new NestedContentConfiguration();}
Inherit from Con�gurationEditor
25 / 59
Con�guration
public class NestedContentConfigurationEditor : ConfigurationEditor<NestedContentConfiguration>{ public override object DefaultConfigurationObject { get; } = new NestedContentConfiguration();}
public class NestedContentConfiguration{ [ConfigurationField("minItems", "Min Items", "number", Description = "Set the minimum number of items allowed.")] public int? MinItems { get; set; }}
Override methods to change behavior
25 / 59
Value editorpublic class NestedContentPropertyValueEditor : DataValueEditor{ public override string ConvertDbToString( PropertyType propertyType, object propertyValue, IDataTypeService dataTypeService) { }}
26 / 59
Value editor
public class NestedContentPropertyValueEditor : DataValueEditor{ public override string ConvertDbToString( PropertyType propertyType, object propertyValue, IDataTypeService dataTypeService) { }}
Inherit from DataValueEditor
26 / 59
Value editor
public override string ConvertDbToString( PropertyType propertyType, object propertyValue, IDataTypeService dataTypeService) { }
public class NestedContentPropertyValueEditor : DataValueEditor{
}
Override methods to change behavior
26 / 59
Data editor[DataEditor("nestedContent", "Nested Content", "nestedcontent", ValueType = "JSON", Group = "lists", Icon = "icon-thumbnail-list")][PropertyEditorAsset(ClientDependencyType.Javascript, "/App_Plugins/PathToAsset.js")]public class NestedContentPropertyEditor : DataEditor{ public NestedContentPropertyEditor(ILogger logger) : base(logger) { } protected override IConfigurationEditor CreateConfigurationEditor() => new NestedContentConfigurationEditor(); protected override IDataValueEditor CreateValueEditor() => new NestedContentPropertyValueEditor();}
27 / 59
Data editor
[DataEditor("nestedContent", "Nested Content", "nestedcontent", ValueType = "JSON", Group = "lists", Icon = "icon-thumbnail-l[PropertyEditorAsset(ClientDependencyType.Javascript, "/App_Plugins/PathToAsset.js")]public class NestedContentPropertyEditor : DataEditor{ public NestedContentPropertyEditor(ILogger logger) : base(logger) { } protected override IConfigurationEditor CreateConfigurationEditor() => new NestedContentConfigurationEditor(); protected override IDataValueEditor CreateValueEditor() => new NestedContentPropertyValueEditor();}
Decorate with DataEditor attribute
27 / 59
Data editor
[PropertyEditorAsset(ClientDependencyType.Javascript, "/App_Plugins/PathToAsset.js")]
[DataEditor("nestedContent", "Nested Content", "nestedcontent", ValueType = "JSON", Group = "lists", Icon = "icon-thumbnail-list")]
public class NestedContentPropertyEditor : DataEditor{ public NestedContentPropertyEditor(ILogger logger) : base(logger) { } protected override IConfigurationEditor CreateConfigurationEditor() => new NestedContentConfigurationEditor(); protected override IDataValueEditor CreateValueEditor() => new NestedContentPropertyValueEditor();}
Optionally register assets, eg scripts and css
27 / 59
Data editor
public class NestedContentPropertyEditor : DataEditor
[DataEditor("nestedContent", "Nested Content", "nestedcontent", ValueType = "JSON", Group = "lists", Icon = "icon-thumbnail-list")][PropertyEditorAsset(ClientDependencyType.Javascript, "/App_Plugins/PathToAsset.js")]
{ public NestedContentPropertyEditor(ILogger logger) : base(logger) { } protected override IConfigurationEditor CreateConfigurationEditor() => new NestedContentConfigurationEditor(); protected override IDataValueEditor CreateValueEditor() => new NestedContentPropertyValueEditor();}
Inherit from DataEditor
27 / 59
Data editor
public NestedContentPropertyEditor(ILogger logger) : base(logger) { }
[DataEditor("nestedContent", "Nested Content", "nestedcontent", ValueType = "JSON", Group = "lists", Icon = "icon-thumbnail-list")][PropertyEditorAsset(ClientDependencyType.Javascript, "/App_Plugins/PathToAsset.js")]public class NestedContentPropertyEditor : DataEditor{
protected override IConfigurationEditor CreateConfigurationEditor() => new NestedContentConfigurationEditor(); protected override IDataValueEditor CreateValueEditor() => new NestedContentPropertyValueEditor();}
Required constructor
27 / 59
Data editor
protected override IConfigurationEditor CreateConfigurationEditor() => new NestedContentConfigura protected override IDataValueEditor CreateValueEditor() => new NestedContentPropertyValueEdit
[DataEditor("nestedContent", "Nested Content", "nestedcontent", ValueType = "JSON", Group = "lists", Icon = "icon-thumbnail-list")][PropertyEditorAsset(ClientDependencyType.Javascript, "/App_Plugins/PathToAsset.js")]public class NestedContentPropertyEditor : DataEditor{ public NestedContentPropertyEditor(ILogger logger) : base(logger) { }
}
Set con�guration and datavalue editor
27 / 59
Property Value Converters
A converts a propertyeditor's database-stored value to another type. The
converted value can be accessed from MVC Razor orany other Published Content API.
Property Value Converter
28 / 59
Property Value Converters
A converts a propertyeditor's database-stored value to another type. The
converted value can be accessed from MVC Razor orany other Published Content API.
For example the standard Umbraco Core "Content
Picker" stores a nodeId or UDI as string. The converterreturns an IPublishedContent object.
Property Value Converter
28 / 59
C# - What changed
V7 V8
InheritPropertyValueConverterBase
InheritPropertyValueConverterBase
ImplementIPropertyValueConverterMeta
or use PropertyValueType andPropertyValueCache attributes
29 / 59
Property Value Converterpublic class OEmbedPickerValueConverter : PropertyValueConverterBase{ public override bool IsConverter(PublishedPropertyType propertyType) { } public override Type GetPropertyValueType(PublishedPropertyType propertyTy public override object ConvertIntermediateToObject(IPublishedElement owner object inter, bool preview) { var allowMultipe = propertyType.DataType.ConfigurationAs<OEmbedPickerConfiguration>() }}
30 / 59
Property Value Converter
public class OEmbedPickerValueConverter : PropertyValueConverterBase{ public override bool IsConverter(PublishedPropertyType propertyType) { } public override Type GetPropertyValueType(PublishedPropertyType propertyTy public override object ConvertIntermediateToObject(IPublishedElement owner object inter, bool preview) { var allowMultipe = propertyType.DataType.ConfigurationAs<OEmbedPickerConfiguration>() }}
Inherit from PropertyValueConverterBase
30 / 59
Property Value Converter
public override bool IsConverter(PublishedPropertyType proper public override Type GetPropertyValueType(PublishedPropertyTy public override object ConvertIntermediateToObject(IPublished object inter, bool preview) { var allowMultipe = propertyType.DataType.ConfigurationAs<OEmbedPickerCon }}
public class OEmbedPickerValueConverter : PropertyValueConverterBase{
Override methods to change behavior
30 / 59
Dashboards
31 / 59
V7 - Registration in con�gRegister by adding entry in /con�g/dashboard.con�g
<section alias="Our.Umbraco.Nexu"> <areas> <area>developer</area> </areas> <tab caption="Nexu"> <control>/App_Plugins/Nexu/views/dashboard.html</control> </tab> </section>
32 / 59
V8 - Package manifestRegister by using the package manifest
{ "dashboards": [ { "alias": "myCustomDashboard2", "view": "/App_Plugins/myCustom/dashboard.html", "sections": [ "content", "settings" ], "weight": -10, "access": [ { "grant": "translator" } ] } ]}
33 / 59
V8 - C# typeRegister by using the C# type
[Weight(-10)] public class MyDashboard : IDashboard { public string Alias => "myCustomDashboard"; public string[] Sections => new[] { "content", "settings" }; public string View => "/App_Plugins/myCustom/dashboard.html"; public IAccessRule[] AccessRules => Array.Empty<IAccessRule>(); }
34 / 59
V8 - Removing dashboard is only possible using C#Removing
[RuntimeLevel(MinLevel = RuntimeLevel.Run)] public class RemoveDashboard : IUserComposer { public void Compose(Composition composition) { composition.Dashboards().Remove<ContentDashboard>(); } }
35 / 59
ExtendingUmbraco
36 / 59
V7 - ApplicationEventHandler
Subscribing Umbraco events or extending Umbraco isdone in a by overriding one
or all of these methods : ApplicationEventHandler
37 / 59
V7 - ApplicationEventHandler
Subscribing Umbraco events or extending Umbraco isdone in a by overriding one
or all of these methods : ApplicationInitialized
ApplicationEventHandler
37 / 59
V7 - ApplicationEventHandler
Subscribing Umbraco events or extending Umbraco isdone in a by overriding one
or all of these methods : ApplicationInitializedApplicationStarting
ApplicationEventHandler
37 / 59
V7 - ApplicationEventHandler
Subscribing Umbraco events or extending Umbraco isdone in a by overriding one
or all of these methods : ApplicationInitializedApplicationStartingApplicationStarted
ApplicationEventHandler
37 / 59
ApplicationEventHandler issues
38 / 59
ApplicationEventHandler issues
Using wrong event
38 / 59
ApplicationEventHandler issues
Using wrong eventNo "real" control over execution order
38 / 59
V8 - composing
39 / 59
V8 - composing
CORE
Composition
39 / 59
V8 - composing
CORE
Composition
U S ER
Composer
39 / 59
V8 - composing
CORE
Composition
U S ER
Composer
U S ER
Components
39 / 59
Composing bene�ts
40 / 59
Composing bene�ts
Control execution moment
40 / 59
Composing bene�ts
Control execution momentControl execution order
40 / 59
Composing bene�ts
Control execution momentControl execution orderEasier replacement or enabling/disabling offunctionality
40 / 59
Composing bene�ts
Control execution momentControl execution orderEasier replacement or enabling/disabling offunctionalityMore predictable, less black magic
40 / 59
Composing documentation
Composing documentationComposing Umbraco V8Composing Umbraco V8 collectionsComposing Umbraco V8 Components
41 / 59
Composer
[RuntimeLevel(MinLevel = RuntimeLevel.Run)] internal class NexuComposer : IUserComposer { public void Compose(Composition composition) { composition.Register<IEntityParsingService, NexuEntityParsingServi composition.Register<IRelationRepository, NexuRelationRepository>( composition.Components().Append<MigrationComponent>(); composition.Components().Append<ContentServiceEventsComponent>(); } }
42 / 59
Composer
[RuntimeLevel(MinLevel = RuntimeLevel.Run)] internal class NexuComposer : IUserComposer { public void Compose(Composition composition) { composition.Register<IEntityParsingService, NexuEntityParsingServi composition.Register<IRelationRepository, NexuRelationRepository>( composition.Components().Append<MigrationComponent>(); composition.Components().Append<ContentServiceEventsComponent>(); } }
Optionally set the Runtime level with attribute
42 / 59
Composer
internal class NexuComposer : IUserComposer [RuntimeLevel(MinLevel = RuntimeLevel.Run)]
{ public void Compose(Composition composition) { composition.Register<IEntityParsingService, NexuEntityParsingServi composition.Register<IRelationRepository, NexuRelationRepository>( composition.Components().Append<MigrationComponent>(); composition.Components().Append<ContentServiceEventsComponent>(); } }
Inherit from IUserComposer
42 / 59
Composer
public void Compose(Composition composition) { composition.Register<IEntityParsingService, NexuEntit composition.Register<IRelationRepository, NexuRelatio composition.Components().Append<MigrationComponent>() composition.Components().Append<ContentServiceEventsC }
[RuntimeLevel(MinLevel = RuntimeLevel.Run)] internal class NexuComposer : IUserComposer {
}
42 / 59
Component
internal class ContentServiceEventsComponent : IComponent { public void Initialize() { ContentService.Saved += this.ContentServiceOnSaved; } public void Terminate() { ContentService.Saved -= this.ContentServiceOnSaved; } }
43 / 59
ContentApps
44 / 59
Not a app that edits content
Content apps
45 / 59
Not a app that edits contentIt's a "companion" for acontent item
Content apps
45 / 59
Not a app that edits contentIt's a "companion" for acontent itemFor non umbraco "content"
Content apps
45 / 59
Not a app that edits contentIt's a "companion" for acontent itemFor non umbraco "content"Limitable by content type, role
Content apps
45 / 59
Not a app that edits contentIt's a "companion" for acontent itemFor non umbraco "content"Limitable by content type, roleRegistered in packagemanifest or C# content appfactory
Content apps
45 / 59
Package manifest
{ "contentApps": [ { "name": "Incoming links", "alias": "nexulinks", "weight": 0, "icon": "icon-nexu", "view": "PathToView", "show": [ "+content/*", "+media/*" ] } ]}
46 / 59
C# Content app factory
public class IncomingLinksApp : IContentAppFactory { public ContentApp GetContentAppFor(object source, IEnumerable<IReadOnl { var app = new ContentApp { Alias = "nexulinks", Name = "Incoming links" Icon = "icon-nexu", View = "PathToView", Weight = 0 }; return app; } }
47 / 59
C# Register content app
[RuntimeLevel(MinLevel = RuntimeLevel.Run)] internal class NexuComposer : IUserComposer { public void Compose(Composition composition) { composition.ContentApps().Append<IncomingLinksApp>(); } }
48 / 59
Migrations
49 / 59
What are migrations
Migrations are used when you want to run setup codeduring startup
50 / 59
What are migrations
Migrations are used when you want to run setup codeduring startup
Create or modify database table
50 / 59
What are migrations
Migrations are used when you want to run setup codeduring startup
Create or modify database tableMigrate data
50 / 59
What are migrations
Migrations are used when you want to run setup codeduring startup
Create or modify database tableMigrate dataRun on each environment when needed
50 / 59
C# - What changed
V7 V8
Version based State based
51 / 59
Migration
public class CreateRelationTableMigration : MigrationBase { public CreateRelationTableMigration(IMigrationContext context) : base(context) { } public override void Migrate() { this.Create.Table("MyTable") .WithColumn("Id").AsGuid().PrimaryKey("PK_Id").NotNullable() .WithColumn("Name").AsString(100).NotNullable() .Do(); } }
52 / 59
Migration public class CreateRelationTableMigration : MigrationBase { public CreateRelationTableMigration(IMigrationContext context) : base(context) { } public override void Migrate() { this.Create.Table("MyTable") .WithColumn("Id").AsGuid().PrimaryKey("PK_Id").NotNullable() .WithColumn("Name").AsString(100).NotNullable() .Do(); } }
Inherit from migration base
52 / 59
Migration
public override void Migrate() { this.Create.Table("MyTable") .WithColumn("Id").AsGuid().PrimaryKey("PK_Id").No .WithColumn("Name").AsString(100).NotNullable() .Do(); } }
public class CreateRelationTableMigration : MigrationBase { public CreateRelationTableMigration(IMigrationContext context) : base(context) { }
Add your migration code
52 / 59
Migration plan
public class NexuMigrationPlan : MigrationPlan { public NexuMigrationPlan() : base("Our.Umbraco.Nexu") { this.From(this.InitialState) .To<CreateRelationTableMigration>("2.0.0-Initial"); } public override string InitialState => string.Empty; }
53 / 59
Migration plan
public class NexuMigrationPlan : MigrationPlan { public NexuMigrationPlan() : base("Our.Umbraco.Nexu") { this.From(this.InitialState) .To<CreateRelationTableMigration>("2.0.0-Initial"); } public override string InitialState => string.Empty; }
Inherit from migration plan
53 / 59
Migration plan
this.From(this.InitialState) .To<CreateRelationTableMigration>("2.0.0-Initial");
public class NexuMigrationPlan : MigrationPlan { public NexuMigrationPlan() : base("Our.Umbraco.Nexu") {
} public override string InitialState => string.Empty; }
Run your migrations depending on state
53 / 59
Migration component public class MigrationComponent : IComponent { private readonly IScopeProvider scopeProvider; private readonly IMigrationBuilder migrationBuilder; private readonly IKeyValueService keyValueService; private readonly ILogger logger; public MigrationComponent(IScopeProvider scopeProvider, IMigrationBuil { // set dependencies } public void Initialize() { var upgrader = new Upgrader(new NexuMigrationPlan()); upgrader.Execute(this.scopeProvider, this.migrationBuilder, this.k }
}
54 / 59
Migration explained
V7 Migrations by SebastianV8 Migrations by Stephane
55 / 59
Packaging
56 / 59
Using the backof�ce
57 / 59
Using the backof�ce
Create a package in the backof�ce
57 / 59
Using the backof�ce
Create a package in the backof�ceOnly support umbraco package format
57 / 59
Using the backof�ce
Create a package in the backof�ceOnly support umbraco package formatError prone
57 / 59
Using the backof�ce
Create a package in the backof�ceOnly support umbraco package formatError prone
A by Paul Sealguide
57 / 59
Automate
58 / 59
Automate
Using a build service
58 / 59
Automate
Using a build serviceListens to git commits on branches
58 / 59
Automate
Using a build serviceListens to git commits on branchesEasy to release beta-versions
58 / 59
Automate
Using a build serviceListens to git commits on branchesEasy to release beta-versionsNuget version
58 / 59
Automate
Using a build serviceListens to git commits on branchesEasy to release beta-versionsNuget version
A by Jeavon Leopoldguide
58 / 59
Questions?
59 / 59