LogoLogo
WinForms to WebPowerBuilder to .NETPowerBuilder to Java
  • WebMAP Documentation | Mobilize.Net
  • WinForms
    • Introduction
    • Getting Started
    • Conversion Process
    • Post-Conversion
    • Extend or Modify the Converted Application
      • NoWebMap Forms Winforms
        • How to add a new Form
        • Adding the created form to the migrated App
        • Interacting with the application data
        • Call the custom API
        • Interaction between the no webmap added Form and the WebMap components
      • Adding a component
      • Adding a component dynamically
      • Add a new control model
      • Switching CSS theme
      • Adding new window
      • Conversion Configuration
        • WebMAP configuration file
        • Stub Filter
      • Adding Non-WebMap Angular Forms
      • Adding FrontEnd Handler to a ToolStripMenuItem
      • Changing ToolStripButton icons
      • Adding new items to existing toolbar
      • Adding FrontEnd element properties and JS listeners
      • Adding FrontEnd output handlers
      • Access FrontEnd components
      • Create custom components based on existing WebMap Component
      • Override FrontEnd methods
    • Assessment Mode
    • Errors and Troubleshooting
      • How to resolve broken reference problems with VBUC
    • Portability
    • Glossary
    • Release Notes
    • Internal Demos
    • Known Issues
    • WinForms DCP
  • WebForms
    • Introduction
    • Overview
    • Desktop Compatibility Platform (DCP)
      • Pages and Master Pages
      • GridView and DataList data synchronization
      • HTTP objects
    • Post-Conversion
    • Extend or Modify the Converted Application
      • Adding FrontEnd validator
      • Adding Page
      • Adding MasterPage
    • Designer classes on WebForms Conversion Tool
    • Errors and Troubleshooting
      • How fix Solution when have been added website from filesystem without project file
    • Release Notes
  • PowerBuilder to .Net
    • Introduction
    • Getting Started
      • Conversion Tool
    • Desktop Compatibility Platform (DCP)
      • Data Manager
    • Reports
      • Report Rendering in Modernized Code
      • ReportWatcher Service Configuration
      • Data Manager to RDL Conversion
      • Reporting Service Internals
      • Troubleshooting
  • PowerBuilder to Java
    • Introduction
    • Getting started
    • Post-Conversion
      • Setup PBJava Environment
      • Architecture
      • App Start
    • Glossary
    • Errors
    • Glossary
    • FAQ
      • How to create a new Control
      • How to create a new Screen
      • What is the Mobilize.WebMAP.CoreServices.All?
      • What is the DesignerAttribute?
      • What is the InterceptedAttribute?
      • What is the InterceptedAttribute?
      • What is the ObservableAttribute?
      • What is the Mobilize.Weaving.WebMAPExtensions.All?
  • General
    • FrontEnd
      • Documentation
        • Webforms Angular Components
          • Web Components
            • Base Components
              • BaseValidator Component
            • KendoUI Components
              • CompareValidator
              • CustomValidator
              • RegularExpressionValidator
              • RequiredFieldValidator
              • ValidationSummary
          • Directives
          • AJAX Web Components
            • AjaxCalendar
            • AjaxModalPopupExtender
          • Ajax Interaction Services
        • Client Core
          • WebMap's Client Core
        • Angular Client
          • Introduction
          • WebMap Service
          • WebMap Interceptor Service
        • Base Components
          • Introduction
          • Components
            • Container
            • Control
            • ControlContainer
            • FormsContainer
            • Loading
            • Stub
        • Winforms Angular Components
          • Web Components
            • Base Components
              • Control Component
              • Form Container
              • Grid Component
              • Style
            • KendoUI Components
              • AdoDataControl
              • Button
              • C1TrueDBGrid
              • CheckBox
              • CheckedListBox
              • ComboBox
              • ContextMenuStrip
              • DataGridView
              • DataGridViewFlex
              • DateTimePicker
              • FileDialog
              • GroupBox
              • Label
              • ListBox
              • ListView
              • MaskedTextBox
              • MessageBox
              • NumericUpDown
              • Panel
              • PictureBox
              • PrintDialog
              • ProgressBar
              • RadioButton
              • RichTextBox
              • StatusStrip
              • Stup
              • TabControl
              • TabPage
              • TextBox
              • Timer
              • ToolStrip
              • TreeView
              • WebBrowser
              • Window
            • JQuery Web Components
          • WebMap FrontEnd Architecture
          • Migrated Structure
          • Setup
            • Front-End setup and compilation
            • Components Manual
            • Browser Support
            • Unit Test Manual
            • Development Process
            • Setup AOT/JIT Compilation
          • Decorators
            • Server Event
          • Conventions
            • Application Structure and NgModules
            • Coding
            • Components
            • Data Service
            • Directives
            • Lifecycle hooks
            • Names
            • Services
        • PowerBuilder Kendo Components
          • Base Components
            • base-component
            • column-control
            • controlcontainer
          • Data Manager Componets
            • base-data-manager
            • data-manager-control
            • data-manager-control-base
            • dw-checkbox
            • dw-column
            • dw-complexNumericMaskComponent
            • dw-compute
            • dw-date-time-edit-mask
            • dw-dropdowndatawindow
            • dw-edit
            • dw-edit-mask
            • dw-radio-button
            • dw-simple-numeric-edit-mask
            • dw-string-edit-mask
            • dw-time-edit-mask
          • Window Components
            • basemask
            • graphics
            • w-checkbox
            • w-command-button
            • w-complex-numeric-mask
            • w-date-time-edit-mask
            • w-dropdownlistbox
            • w-group-box
            • w-line
            • w-listbox
            • w-maskedtextbox
            • w-mdiclient
            • w-menu
            • w-multiline
            • w-picture
            • w-picture
            • w-radiobutton
            • w-rectangle
            • w-simple-numeric-edit-mask
            • w-single-line-edit
            • w-statictext
            • w-string-edit-mask
            • w-time-edit-mask
            • w-toolbar
            • w-toolbaritem
            • w-user-object
            • w-window
          • Services
            • DmInteractionService
          • DataManagerEvents
          • FocusManager guide
      • Api Documentation
        • WebMap Silverlight
        • WfNetC1Components
        • WebFormsComponents
      • Guides
        • Setup NPM package registry in the workspace
        • How to Setup WebMap Applications To Run Over SubDomains or WebApplications In IIS
        • Deploy several WebMap Apps in the same Server
        • Update to Angular 16
        • Appearance
          • How to change the CSS
          • How to override the style for a component
        • Component maintenance
          • How link WebMap package to the migrated Application
          • How to resolve broken reference problems with VBUC
          • How to test a local WebMap Components package
          • How to add a new component in a migrated application
          • How to update a component
          • Dynamic Control Support
          • How to add new set of component with a different provider
          • How to test your component in the playground
          • Tools
        • WMLogger
          • How to use the WMLogger's instance
          • How to change log's level
          • How to add log tags
        • Integration test
        • Setup WebMap Applications to Run Front-End And Back-End In Separates Sites
          • Setup WebMap Applications To Run Front-End And Back-End In Separates Sites in Production (IIS)
        • Setup Migrated WebMap Applications To Run Front-end & Back-end In Separates Sites (Only development)
        • Initial Set Up
          • Software to Install
          • Necessary Repositories
      • Errors
      • Version Notes
        • Client Core
        • Angular Client
        • Web Base Components
        • Winforms Angular Components
        • PowerBuilder Kendo Components
      • Licenses
        • Client Core
        • Angular Client
        • Base Components
        • PB Kendo Components
        • WFNet Kendo Components
        • WebForms Components
        • WFNet Access Components
        • WFNet Janus Components
        • WFNet C1 Components
        • Silverlight wms-framework
        • Silverlight i-components
    • BackEnd
      • WebMAP From Scratch
      • Setup
      • DCP: Desktop Compatibly Platform
        • Overview
        • Library Bundles
          • Bundle Library
            • Create an Observable Object
          • Bundle DTO
            • DTO: Data Transfer Objects
              • Creating a DTO
            • Mappers
              • Create Mappers
            • Observable Wrappers
              • Create an Observable Wrapper
            • API/Controllers
      • Architecture
      • Weaving on WebMAP
      • Glossary
      • FAQ
        • How to create a new Control
        • How to create a new Screen
        • What is the Mobilize.WebMAP.CoreServices.All?
        • What is the DesignerAttribute?
        • What is the InterceptedAttribute?
        • What is the Mobilize.Extensions.Logging.RollingFile?
        • What is the ObservableAttribute?
        • What is the Mobilize.Weaving.WebMAPExtensions.All?
      • Licenses
        • PBNet DCP
        • WebFormsDCP
        • WFNet DCP
        • CoreServices
        • CoreServicesCommon
    • Request and Response
  • SCALABILITY
    • Introduction
    • Microservices
    • Containerizing a WebMap .Net Application with Docker
    • Vertical scalability
Powered by GitBook
On this page
  • Writing your Mapper
  • Mapper registration
  • Using the ObservableExtensions
  • Creating Mappers with Factories

Was this helpful?

  1. General
  2. BackEnd
  3. DCP: Desktop Compatibly Platform
  4. Library Bundles
  5. Bundle DTO
  6. Mappers

Create Mappers

PreviousMappersNextObservable Wrappers

Last updated 3 years ago

Was this helpful?

Writing your Mapper

A class mapper must implement the IMapper interface from Mobilize.WebMap.Common.Messaging. The first type parameter of this generic interface should be the model. The second parameter of the generic interface is the DTO class. For information on creating your mappers see the .

This interface has three methods:

  • Map this method is called to create a DTO instance and populate from the model. If you do not want to send anything to the client you can return null

  • ApplyChanges this method is called to sync back data from the client. In this method you can take data sent from the client and apply those changes to the model on the backend.

  • Configure this method is called to setup which data elements from the model must be considered as references.

A possible mapper for the previous DTO can be like the following code:

    public class ButtonMapper : IMapper
    {
        public void ApplyChanges(IObservable observable, IDataTransfer dto)
        {
            var target = observable as Models.Button;
            var source = dto        as DataTransfer.Button;
            this.Map(source, target);
        }

        public void Configure(MapperInformation config)
        {
            // There is no references to configure
        }

        public object Map(IObservable observable)
        {
            var source = observable as Model.Button;
            var target = new           DataTransfer.Button();
            this.Map(source, target);
            return target;
        }

        private void Map(Models.Button observable, DataTransfer.Button dto)
        {
            dto.Text = observable.Text;
            dto.Name = observable.Name;
        }

        private void Map(DataTransfer.Button dto, Models.Button observable)
        {
            observable.Name = dto.Name;
            observable.Text = dto.Text;
        }
    }

Mapper registration

Mappers need to be registered in a Registration class in order to be able to be accessed during the request/response execution. A mapper is specifically associated to a type, so, when each button in an application will always trigger the ButtonMapper to synchronize data.

catalog.AddMapper(new DmColumn());

Using the ObservableExtensions

You can also use using Mobilize.WebMAP.Common.Core to include the ObservableExtensions. This will extensions add helper methods that can be used for several tasks.

NullableTypes

If you define properties like public int? Value then the null value can be used when we know that those properties do not need to be sent.

For example with this code:

dto.Value = model.GetChanged(x => x.Value);

The extension method GetChanged will return null. Null values on the current formatting settings will not be sent.

Getting Events or Delegates

To get information about model delegates you can use several extensions methods.

For example to get information about all model delegates (regardless of whether they have been modified on the current request or not):

 Dictionary events = model.GetDelegates();

This will return a dictionary where each key is the Event or Delegate name and the value is a boolean value indicating if those events or delegates have a handler.

You can use restrict which events or delegates you need. For example:

 Dictionary events = model.GetDelegates(x => x.Click, x => x.KeyPress);

You can also send only the events or delegates that changed during a request:

 Dictionary events = model.GetDelegatesChanged(x => x.Click, x => x.KeyPress);

Sending private properties

Mappers and DTO should be created on a different assembly that the one where the model is defined. However, that makes it impossible to access private properties.

A recommendation is to make these properties internal or expose them thru an internal property. And then add a InternalsVisible('MappersAndDTOAssemblyName') attribute to the models assembly. This will allow using this internals from the mappers.

Avoid setting properties with side effects

As a recommendation, if you have a property getter or setter that has some logic avoid using them directly and prefer to set other properties without any side effects.

Handling Calculated properties

Sometimes you cannot avoid using calculated properties. The problem with calculated properties is that the GetChanged extension only works on properties with the Intercepted attribute.

Let's see how to handle it on a hypothetical calculated property CalculatedProperty1. Let's say that this property depends on PropertyA and Reference.PropertyB then in your mapper you can create a method like:

private bool GetCalculatedProperty1Changed(SomeModel model) 
{
   if (model.GetChanged(x => x.PropertyA)!=null && model.Reference?.GetChanged(x => x.PropertyB))
   {
     return model.CalculatedProperty1;
   }
   return null;
}

Creating Mappers with Factories

There are situations where you have types that are not completely known beforehand for example for generic types. In this case, you can create a factory class that will be used whenever a mapper is not found.

The mapper registration works only for a specific type, which, means that only if a control is of the same type that is registered it will be take part of the mapping process, although, in some cases it may be necessary to register different types to a particular mapper, in these cases WebMap provides a MapperFactory which is used to register several types to a Mapper. For example, if there is a GenericButton class that inherits from Button, by registering directly a Mapper it would only connect the Button type to it, but, if a MapperFactory is registered, both the Button and GenericButton class would go through the same mapper.

Let's say that you have a generic component Button then the factory will be something like:

    public class GenericButtonMapper
    {

        bool CanGetMapper(Type type) { returns type.IsGeneric && typeof(Button<>).IsAssignableFrom(type.GetGenericTypeDefinition());}

        /// 
        /// Gets the mapper.
        /// 
        /// The type.
        /// The type for the mapper
        MapperInformation GetMapperInformation(Type type) 
        {
             var mapperType = typeof(ButtonMapper<>).MakeGenericType(type.GetGenericArguments()[0]);
             var dtoType = typeof(ButtonDataTransfer<>).MakeGenericType(type.GetGenericArguments()[0]);
             var mapper = Activator.CreateInstance(mapperType);
             var mapperId = "btn" + type.GetGenericArguments()[0].Name;
             new MapperInformation(mapperId, type, dtoType, mapper);           
        }
    }

This factory will return a new ButtonMapper instance using T as InType and ButtonDataTransfer as OutType

Creating a DTO